假设数组为arr,求第k大元素
思想:利用快排思想,对数组先进行一趟快排,将数组进行分区arr[0...p-1],arr[p],arr[p+1,arr.length-1](p是索引元素的下标),紧接着判断p+1与k的关系,如果p+1=k,那么arr[p]就是第k大元素,如果p+1<k,则对arr[p+1,arr.length-1]进行上述操作,反之对arr[0,p-1]进行上述操作
时间复杂度分析:
* 第一次分区查找,我们需要对大小为 n 的数组执行分区操作,需需要遍历 n 个元素。第二次分区查
* 找,我们只需要对大小为 n/2 的数组执行分区操作,需要遍历n/2 个元素。依次类推,分区遍历
* 元素的个数分别为n、n/2、n/4、n/8、n/16.……直到区间缩小为 1。
*
* 如果我们把每次分区遍历的元素个数加起来,就是:n+n/2+n/4+n/8+…+1。这是一个等比数列求和,最后的和等于 2n-1。
* 所以,上述解决思路的时间复杂度就为 O(n)
*
* 利用快排分区的思路:数组按降序排序的方式获取每次provt[i]的坐标来进行判断
实现代码如下:
public class ApplicationQuickSort {
public static void main(String[] args) {
int[] arr = {2,5,8,6,4,1,2,4,1,4,10,1,5,4,1,4,5,1,-2,5,2,4,5,5,2,100,4};
int t = Partition(arr,0,arr.length-1);
System.out.println(t);
int k = 1;
while(t+1!=k){
if(t+1<k){
t = Partition(arr,t+1,arr.length-1);
}else if(t+1>k){
t = Partition(arr,0,t-1);
}
}
System.out.println(arr[t]);
}
public static int Partition(int[] arr,int start,int end){
if(start<end){
int tmp = arr[start];
while(start<end){
int t = 0;
while(tmp >= arr[end]&&start<end){
end--;
}
if(start<end){
arr[start] = arr[end];
start++;
}
while(arr[start] >= tmp&&start<end){
start++;
}
if(start<end){
arr[end] = arr[start];
end--;
}
}
arr[start] = tmp;
return start;
}
return -1;
}
}