您的位置:首页 > 其它

(p123)最坏情况为线性时间的选择算法

2016-02-16 17:01 295 查看
<span style="font-family: Arial, Helvetica, sans-serif;">/*</span>
* select.c
*
*  Created on: Feb 16, 2016
*      Author: wing
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int sort(int *num,int l,int r)
{
int i,j,x;
for (i=l+1;i<=r;i++)
{
x=num[i];
j=i-1;
while(j>=l&&num[j]>x)
{
num[j+1]=num[j];
j--;
}
num[j+1]=x;
}
return num[(l+r)/2];
}
int find(int *num,int k,int n,int l,int r)/*在l到r区间内找输入数组中第k小的元素,其中当前区间总元素数为n*/
{
if (l==r)return num[l];
int i,*tmp,mid,j,t;
tmp=(int *)malloc(sizeof(int)*((int)ceil(n/5.0)));/*ceil是向上取整,头文件是math.h,eclipse使用前需要先在属性的库设置那里加上m*/
for (i=1;i<=n/5;i++)
tmp[i-1]=sort(num,l+(i-1)*5,l+i*5-1);
if (n%5)
tmp[i-1]=sort(num,l+(i-1)*5,l+n-1);/*把数组分成一个一个的5元数组,对每个数组进行插入排序,将所有中位数组成一个新的数组tmp*/
mid=find(tmp,(int)ceil(ceil(n/5.0)/2),(int)ceil(n/5.0),0,(int)ceil(n/5.0)-1);/*找中位数的中位数,用来做分解的标志*/
j=l-1;
for (i=l;i<=r;i++)
if (num[i]<=mid)
{
j++;
t=num[j];
num[j]=num[i];
num[i]=t;
}/*和快排的partition一样*/
if (k-1==j)
return mid;
else
if (k-1<j)
return find(num,k,j-l+1,l,j);
else
return find(num,k,r-j,j+1,r);
};
int main(void)
{
int *num,i,n,k,a;
scanf("%d",&n);
num=(int *)malloc(sizeof(int)*n);
for (i=0;i<n;i++)
scanf("%d",&num[i]);
scanf("%d",&k);
a=find(num,k,n,0,n-1);
printf("%d",a);
return 0;
}


不得不说,书上的这个算法实在是太牛了,没想到一个选择问题也可以引申出这么多算法,只有想不到,没有做不到——虽然写这个代码也写了很久,debug了一天...没关系,慢慢来,这对代码能力提高还是挺有用的^-^
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: