摘要:选择第k小的元素,用快速排序的思想可以以平均O(NlogN)的时间界做到.
(1)首先找到中间值,并且进行排序。
(2)如果左边的子序列的长度|S1|==k-1,那么很显然中间值就是所求.
(3)如果左边的子序列的长度|S1| >=k,那么显然这个所求元素就在子序列S1里面,递归的在S1里面求解;
(4)如果|S1| < k-1那么k就在S2中.
(5)如果遇到一个小的子序列(子序列的长度很小),那么我们就用插入排序将它排序,然后返回第k个最小元;
代码:
void Quickselect(int *A,int Left,int Right,int order)//选择第order个最小元
{
int Pivot,i,j;
if (Left + cutoff <= Right)
{
Pivot = Median3(A,Left,Right);
//进行分割
i = Left, j = Right - 1;
while(1)
{
//直到i,j交错为止
while(A[++i] < Pivot){};
while(A[--j] > Pivot){};
if(i < j)
swap(&A[i],&A[j]);
else
break;
}
if (order < i+1)//注意order排序好之后的下标
Quickselect(A,Left,i-1,order);
else if (order > i+1)
Quickselect(A,i+1,Right,order);
}
else
Insertsort(A+Left,Right - Left + 1);
}
int QuickS(int *A,int N,int order)//快速选择算法的驱动例程
{
int *memory = (int *)malloc(sizeof(int)*N);
int k;
memcpy(memory,A,N*sizeof(int));
Quickselect(A,0,N-1,order);
k = A[order - 1];
memcpy(A,memory,N*sizeof(int));
return k;
}