参考算法设计与分析。
#include <bits/stdc++.h>
using namespace std;
inline int Random(int x,int y)
{
int ran=rand()%(y-x)+x;
return ran;
}
int Partition(int a[],int p,int r,int k)
{
int i=p-1;
int j=r+1;
while(true)
{
while(a[++i]<k&&i<r);
while(a[--j]>k);
if(i>=j)
break;
swap(a[i],a[j]);
}
return j;
//返回i跟返回j是一样的。
}
int Select(int a[],int p,int r,int k)
{
if(r-p<=75)
{
sort(a+p,a+r+1);
return a[k+p-1];
}
//(r-p-4)相当于n-5;
//将元素5个分为一组,分别排序,并将该数组的中位数与a[p+i]交换位置
//将所有中位数都排在数组最左侧,以便进一步查找中位数的中位数.
for(int i=0;i<=(r-p-4)/5;i++)
{
sort(a+p+i*5,a+p+i*5+5);
swap(a[p+i],a[p+i*5+2]);
}
int x=Select(a,p,p+(r-p-4)/5,(r-p-4)/10);//找中位数的中位数。
int i=Partition(a,p,r,x);//找寻中位数的位置;
int j=i-p+1; //记得这块得改变k在数组中的位置。
if(i>k)
Select(a,p,i,k);
else
Select(a,i+1,r,k-j);//记得这块得改变k在数组中的位置
}
int main()
{
int a[100];
srand((unsigned)time(0));
for(int i=0;i<100;i++)
a[i]=Random(0,500);
cout<<endl;
printf("第83小元素是%d\n",Select(a,0,99,83));
//重新排序,比较结果。
sort(a,a+100);
printf("a[82]=%d\n",a[82]);
return 0;
}