给定一个无序的数组,输入第n大,输出第n大的数。(顺便排序)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define max 5
int randpartition(int a[],int low, int high){
int s=round(1.0*rand()/RAND_MAX*(high-low)+low);
int temp=a[s];
a[s]=a[low];
a[low]=temp;
int pivot=a[low];
while(low<high){
while(low<high&&a[high]>=pivot) high--;
a[low]=a[high];
while(low<high&&a[low]<=pivot) low++;
a[high]=a[low];
}
a[low]=pivot;
return low;
}
//
int randselect(int a[],int low,int high,int n){
if(low==high) return a[low];
int p=randpartition(a,low,high);//4 di 3 da p=2
int m=p-low+1;
if(m==n){
return a[p];
}
if(m<n){
randselect(a,p+1,high,n-m);//最重要的部分就是n-m
}else{
randselect(a,low,p-1,n);
}
}
void randsort(int a[]){
int key,low=0,high=max-1;
for(int i=1;i<=5;i++){
key=randselect(a,low,high,i);
printf("%d ",key);
}
putchar('\n');
}
int main(){
int a[]={1,4,9,2,6};
//int n;
//srand((unsigned)time(NULL));
//printf("input index of the array :\n");
//scanf("%d",&n);
//int low=0,high=max-1;
// int key=randselect(a,low,high,n);
// printf("%d\n",key);
randsort(a);
return 0;
}
1、算法整体分为两个部分
randselect() 用于递归,所以会有递归边界和递归条件
randselect 里面有 randpartition 是用来随机选择一个 数,并确定其数组下标(partition用到了快排的思想,对于这个枢纽,左边小,右边大),若刚好等于n,则返回其值。
否则 若m>n即 得到的是比第n 小的数,则递归 仍然是第m小的
m<n 注意 (我就是在这一直错)要传的是 第n-m大的,相当于重头开始!!
2、第 ?大 m大=p-low+1 我觉得是用特殊值 举例。
3、据说时间复杂度是On 如果是排序后选择,是O nlogn