- #include<stdio.h>
- #include<stdlib.h>
-
- int main()
- {
- void sord(int a[],int h,int t);
- int selectorder(int x,int a[],int h,int t);
- int partition(int a[],int h,int t,int k);
- int n;
- scanf("%d",&n);
- int *a;
- a=(int *)malloc(sizeof(int)*n);
- for(int i=0;i<n;i++)
- a[i]=rand();
- for(int i=0;i<n;i++)
- printf("%d ",a[i]);//动态创建数组a并随机生成数组a元素、输出
- /*
- int n=15;
- int a[15]={41,58,96,7,5,857,589,415,27,398,215,86,71,88,85};
- for(int i=0;i<n;i++)
- printf("%d ",a[i]);*/ //检查程序时用的数组
- printf("\n");
- int k;
- scanf("%d",&k);//输入k
- int answer;//order-1
- if(k>n)printf("scan error");//k>n,输入错误
- else
- {
- answer=selectorder(k-1,a,0,n-1);//调用selectorder函数,
- //得到第k小元素并赋值给answer
- printf("%d\n",answer);
- }
- sord(a,0,n-1);
- for(int i=0;i<n;i++)printf("%d ",a[i]);//对数组a中元素进行选择排序、输出,为了检查程序
- return 0;
- }
- void sord(int *a,int h,int t)//对数组a中(从第h个到第t个)元素进行选择排序
- {
- int temp;
- int i,j;
- for(i=h;i<=t-1;i++)
- for(j=i+1;j<=t;j++)
- if(a[i]>a[j])
- {temp=a[i];a[i]=a[j];a[j]=temp;}
- }
- int partition(int *a,int h,int t,int k)//根据元素k将数组a(从第h个到第t个)
- //划分成元素小于k的左半部分和大于k的右半部分
- {
- int i=h;
- int j=t;
- int temp;
- while(i<j)
- {
- while(a[i]<k)i++;
- while(a[j]>k)j--;
- temp=a[i];a[i]=a[j];a[j]=temp;
- }
- for(int j=h;j<=t;j++)if(a[j]==k)break;
- a[j]=a[i];a[i]=k;
- return i;
- }
-
- int selectorder(int x,int *a,int h,int t)
- {
- if(t-h+1<75)
- {
- if(t>h)sord(a,h,t);
- return a[x];
- }//如果当前数组范围内元素个数小于75,
- //对此范围内数组元素进行选择排序并返回a[x]
- else
- {
- int i;
- int temp;
- for(i=0;i<=(t-h-4)/5;i++)
- {
- sord(a,h+i*5,h+i*5+4);
- temp=a[h+i];
- a[h+i]=a[h+i*5+2];
- a[h+i*5+2]=temp;
- }//将n个元素划分成?n/5?个组,
- //对每个组进行选择排序,
- //将每个组的中位数调到数组前部
- int k=selectorder(h+((t-h-4)/5)/2,a,h,h+(t-h-4)/5);
- //找出位于数组前部中每个组的中位数中的中位数
- i=partition(a,h,t,k);
- //根据k对数组a(从第h个到第t个)进行划分,
- //左边元素值比k小,右边元素比k大,
- //返回i为k在数组中的位置
- if(i==x)return(a[i]);//找到数组中第x+1小元素
- else
- {
- int j=i+1;
- if(x<j)return selectorder(x,a,h,i-1);//从k的左半部分数组元素中找第x+1小元素
- else return selectorder(x,a,j,t);//从k的右半部分数组元素中找第x+1小元素
- }
- }
- }