线性时间选择算法实现
void swap(int *a,int *b);
//主函数
int main()
{
int *a,cnt,i,k,result;
FILE *fp;
//clrscr();
printf("Input the count of elements:");
scanf("%d",&cnt);
printf("Choose the element :");
{
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;
}
void sort(int *a,int p,int r)
}
for(i=0;i<cnt;i++)
{
a[i]=rand()%cnt+100;
fprintf(fp,"%4d\n",a[i]);
}
result=select(a,0,cnt-1,k);
printf("The result is:%d",result);
fclose(fp);
free(a);
return 0;
if(k<=j) //比较k和j来确定在数组哪一部分继续选择
return select(a,p,i,k);
else
return select(a,i+1,r,k-j);
}
int partition(int *a,int p,int r,int x)
//以x为基准,将a[p...r]分割成两部分,并返回x的下标。
【题目】:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的) 【思路】:如果能在线性时间内找到一个划分基准,使得按这个基准所划分出的2个子数组的长度都至少为原数组长度的ε倍(0<ε<1是某个正常数),那么就可以在最坏情况下用O(n)时间完成选择任务。例如:若ε=9/10,算法递归调用所产生的子数组的长度至少缩短1/10。所以,在最坏情况下,算法所需的计算时间T(n)满足递归式T(n)≤T(9n/10)+O(n) 。由此可得T(n)=O(n)。
{
sort(a,p+5*i,p+5*i+4);
swap(&a[p+5*i+2],&a[p+i]);
}
temp=select(a,p,p+(r-p-4)/5,(r-p-4)/10);//找中位数的中位数为划分基准
i=partition(a,p,r,temp); //依照基准划分原数组,并返回基准下标
j=i-p+1; //基准下标为a[p.....r]的第几个元素,与k的形式相同
//对a[p...r]进行冒泡排序
{
int i,j,temp;
for(i=p;i<r;i++)
{
for(j=r;j>i;j--) //此处r为下标,j的范围应该最大为r-1
if(a[j-1]>a[j])
{
temp=a[j-1];
a[j-1]=a[j];
a[j]=t}
void swap(int *a,int *b)
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
int select(int *a,int p,int r,int k);
int partition(int *a,int p,int r,int x);
void sort(int *a,int p,int r);
scanf("%d",&k);
a=(int *)malloc(cnt*sizeof(int));
srand(time(NULL));
if((fp=fopen("d:\\output.txt","w+"))==NULL)
{
printf("Cannot open this file!");
exit(0);
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
}
int select(int *a,int p,int r,int k) //程序核心部分
{
char filename[10];
int i,j,temp;
if(r-p<75) //数组元素小于75个的时候,用简单排序法进行排序
{
sort(a,p,r);
return a[p+k-1];
}
for(i=0;i<(r-p-4)/5;i++) //将cnt个元素每5个元素分成一组,分别排序,并将该组中位数与a[p+i]交换位置。循环执行完后,所有组的中位数集中到数组前a[0....(r-p-4)/5-1].