题目
给定一个数组包含n个元素,统计前m大的数并且把这m个数从大到小输出。
思路
直接进行排序输出也可以,只是时间复杂度略大。先挑出前m个,然后在排序输出则会好一些。此办法对应用于总数很大,m较小的情况。
找出前m大的数,可参考快排的思路。对于一组数,找出一个key,然后将其他元素划分到key的左右两侧。
需要注意的是:
- 再每次搜索时,要缩小范围。
- 与key相等的情况,放在key的左右都行
#include <stdio.h>
using namespace std;
int t(int a[],int b,int e){
if(b< e){
int i=b,j=e,t;
while(i != j){
while(i<j && a[j]<=a[i]){ //=
j--;
}
t = a[j];
a[j] = a[i];
a[i] = t;
while(i<j &&a[i]>=a[j]){ //=
i++;
}
t = a[i];
a[i] = a[j];
a[j] = t;
}
return i;
}
return -1;
}
void find(int a[],int len, int m){//100,10
int base = 0,in = t(a,0,len-1);
base = in;
while(in != -1){
//printf("2\t%d \n",in);
if(in+1==m){
return ;
}else if(in+1 >m){
in = t(a,0,in-1); // in-1
}else{
in = t(a,in+1,len-1); // in+1
}
}
}
void sort(int a[],int b,int e){
if(b<e){
int in = t(a,b,e);
if(in != -1){
sort(a,b,in-1);
sort(a,in+1,e);
}
}
}
int main(){
int a[100]={93,27,30,2,8,12,2,8,30,89};
find(a,10,5);
for(int i=0;i<5;i++)
printf("%d ",a[i]);
sort(a,0,5);
for(int i=0;i<5;i++)
printf("%d ",a[i]);
}