1 .问题
在有n个整数的数组S中, 选第k小的元素。
2.解析
3.设计
//核心算法
int select(int a[],int left,int right,int k)
{
int n=right-left;//计算数组规模大小
//小于5时直接用二分归并排序
if (n<5){
merge_sort(a,left,right-1);
return a[left+k-1];
}
int i;
int t=n/5;//每五个一组,分为t组
int *m = new int[t];
for (i=0;i<t;i++) {//求中位数数组
merge_sort(a,left+i*5,left+i*5+5-1);
m[i] = a[left+i*5+2];
}
merge_sort(m,0,i-1);
int mid=m[i/2];//求中位数数组中的中位数mid
int *a1=new int[n];
int *a2=new int[n];
int *a3=new int[n];
int s1=0,s2=0,s3=0;
for(int i=left;i<right;i++)
{
if(a[i]<mid)//元素小于mid存入a1数组
{
a1[s1++]=a[i];
}
else if(a[i]==mid)//元素等于mid存入a2数组
{
a2[s2++]=a[i];
}
else//其余元素存入入a3数组
a3[s3++]=a[i];
}
if(s1>=k)//如果小于mid的个数大于或等于k
{
return select(a1,0,s1,k);
}
if (s1+s2>=k)//如果小于mid的个数加上等于mid的个数大于或等于k个
{
return mid;
}
else//其他情况
return select(a3,0,s3,k-s1-s2);
}
4.分析
算法复杂度
O(n)
5.码源
源码地址: https://github.com/chaoxing0910/ex6