算法基本思想是对输入的数组进行递归划分,这样得到一个中轴元素pivot,左边数组内的数都小于等于中轴元素pivot,右边的数组都大于等于pivot,然后考察右边边数组加上中轴元素的个数x,若个数x==k,则返回pivot;若x>k,则说明第K大元素在右边数组并且是第k大元素,继续递归查找;若x<k,则说明第K大元素在左边边数组并且是第k-x大元素。综合上面的思想得到代码如下:
int random(int x,int y){
if(x>y)
return random(y,x);
srand(GetTickCount());
return rand()%(y-x+1)+x;
}
int randomizedPartition(int *A,int low,int high){
int p=random(low,high);
//exchange A[0]<->A[p]
int key=A[low];
A[low]=A[p];
A[p]=key;
//set the key value
key=A[low];
while(low<high){
while(low<high&&A[high]>=key)high--;
A[low]=A[high];
while(low<high&&A[low]<=key)low++;
A[high]=A[low];
}
A[low]=key;
return low;
}
int randomizedSelect(int *A,int s,int t,int i){
if(s==t)
return A[s];
int p=randomizedPartition(A,s,t);
int k=t-p+1;
if(k==i)
return A[p];
else if(k>i)
return randomizedSelect(A,p+1,t,i);
else
return randomizedSelect(A,s,p-1,i-k);
}
这里用的是C语言实现,随机数函数还是有点问题有待完善.其实求第K大的数和求第K小的数本质上是一样的,必须有这种解决问题的思想!