您的位置:首页 > 其它

线性时间选择第k小(递归)

2016-12-28 19:49 337 查看
利用O(N)时间选择第k小,思路是五个一组,找到五个的中位数,再在中位数里找中位数,作为partition的pivot;

#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;

const int N=50000;//数组大小
int a
;

int ppartition(int p,int r,int x)
{
//int x=a[p];
int i=p,j=r+1;
while(1)
{
while(a[++i]<x&&i<r);
while(a[--j]>x);
if(i>=j)break;
swap(a[i],a[j]);
}
//a[p]=a[j];
//	a[j]=x;
return j;
}
int Select(int p,int r,int k){
if(r-p<75){
sort(a,a+N);
return a[p+k-1];
}

for(int i=0;i<=(r-p-4)/5;i++){
sort(a+p+5*i,a+p+5*i+5);
swap(a[p+i],a[p+5*i+2]);
}
int x=Select(p,p+(r-p-4)/5,(r-p-4)/10);
int i=ppartition(p,r,x);int j=i-p+1;
if(k<=j)return Select(p,i,k);
else return Select(i+1,r,k-j);
}
int main()
{
for(int i=0;i<N;i++)a[i]=i+1;

cout<<"请选择要输出的第k小的数字:"<<endl;
int k;cin>>k;

int ans=Select(0,N-1,k);
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: