基本思想:在快速排序的基础上进行改进。
时间复杂度:O(nlogn)。
具体代码如下:
package test;
public class Test {
public static int N = 4; //找出最小的4个数
public static void QuickSort(int a[],int left,int right){
int i=left;
int j=right;
int temp = a[i];
if(left>=right)
return ;
while(i<j){
while(i<j&&a[j]>temp)
j--;
if(i<j){
a[i++]=a[j];
}
while(i<j&&a[i]<temp){
i++;
}
if(i<j){
a[j--]=a[i];
}
}
a[j]=temp;
if(i>N && left<N) //在中轴数左边继续寻找
QuickSort(a,left,i-1);
if(i<=N && right>=N) //在中轴数右边继续寻找
QuickSort(a,i+1,right);
}
public static void main(String[] args) {
int array[] = { 1, 5, 2, 9, 4, 3, 7, 8, 6, 10 };
QuickSort(array,0,N);
for(int i=0;i<N;i++)
System.out.print(array[i]+" ");
//System.out.print(Arrays.toString(array));
}
}
寻找无序数组中的第K大数和前K大数,两个问题互相可以转化。如果可以找到第K大数,那么只再需要O(N)就可以找齐剩余的前K大数。如果可以找到前K大数,那么只再需要O(K)就可以找到第K大数。
先排序,在找第K个。O(NlgN)快速排序的思想,可以做到平均效率O(N)
随机选一个元素,把所有小于等于这个元素的数移到左边,所有大于这个元素的数移动到右边。如果这个元素成了第K个数,直接返回这个数。
如果左边的个数大于K,不管右边的数了,在左边重复上面的过程。
如果左边的个数等于T<K,不管左边的数了,重复上面的过程,只是K=K-T-1。
平均情况下,第一次划分的时间复杂度是O(N),第二次是O(N/2),总共是O(N+N/2+N/4+...)=O(N)
package test;
public class Test {
public static int QuickSort(int a[],int left,int right,int K){
int i=left;
int j=right;
if(K>right-left+1)
return -1;
if(left>right)
return -1;
int temp = a[i];
while(i<j){
while(i<j&&a[j]>temp)
j--;
if(i<j){
a[i++]=a[j];
}
while(i<j&&a[i]<temp){
i++;
}
if(i<j){
a[j--]=a[i];
}
}
a[i]=temp;
int move = i-left+1; //已经移动的步数,关键!
if(move==K){
return a[i];
}
else if(move>K){
return QuickSort(a,left,i-1,K);
}
else{
return QuickSort(a,i+1,right,K-move);
}
}
public static void main(String[] args) {
int array[] = { 1, 5, 2, 9, 4, 3, 7, 8, 6, 10 };
int k = 5;
System.out.println(QuickSort(array,0,9,k));
}
}