思路:在基础版本的选择算法上,保证每一次都是平衡的划分
#include<iostream>
using namespace std;
int a[1000];
int part(int b,int r,int x)//划分
{
swap(a[x],a[r]);
int i=b-1;
int j=b;
while(j<=r)
{
if(a[j]<a[r])
{
swap(a[j],a[i+1]);
i++;
}
j++;
}
swap(a[i+1],a[r]);
return i+1;
}
void sort(int b,int r)//选择排序
{
for(int i=b;i<r;i++)
{
for(int j=i+1;j<=r;j++)
{
if(a[i]>a[j]) swap(a[i],a[j]);
}
}
}
int select(int b,int r,int k)//选择算法
{
if(r-b<5)//临界条件,当小于5个数时,直接排序即可
{
sort(b,r);
return a[b+k-1];
}
int g=(r-b+1)/5;
int j=1;
int t=b;
int p=b;
while(j<=g)//每5个分成一组。找出每组的中位数
{
sort(t,t+4);
swap(a[p],a[t+2]);//把中位数都放到前面的第p个位置,以便进行排序找出中值的中值
t=t+5;
p++;
j++;
}
int y=(r-b+1)%5;
if(y!=0)
{
sort(t,t-1+y);
swap(a[p],a[t+y/2]);
g++;
}
sort(b,b+g-1);
int x=(g+b-1+b)/2;//中值的中值的下标
int pos=part(b,r,x);//进行划分
int m=pos-b+1; //用个数来比较更简洁
if(k<m) return select(b,pos-1,k);//递归
if(k==m) return a[pos];
if(k>m) return select(pos+1,r,k-m);
}
int main()
{
int n,k;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>k;
cout<<select(1,n,k);//寻找第K位
}