一个有N个整数组成的数组,写一个函数,找出数组中最大的K个数 例如:N=1000000 K=10 在线等!!!

用C++编写,方法是用数组存储K个数,排好序,然后N-K个数逐个与K个数中的数比较,去掉小数,把那个数存入数组再排序。我正在考虑时间复杂度的问题。求代码~~希望能用我的方法来写代码!

利用快排的思想,利用函数Partition()分段。①若pivot左边的数个数小于K,则输出包括pivot在内的左边的数(假设为m个,m <=K),然后以pivot右边的数组为源数组,在其中查找前K-m个最大的数。②否则,如果pivot(含)左边的数的个数大于K,则以其左边的这一段为查找子集,找其中K个最大的数。
从整个描述上来看,这是一个递归的过程,所以实现里用到了递归。代码如下:
/*
一个有N个整数组成的数组, 写一个函数, 找出数组中最大的K个数 例如:N=1000000 K=10
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int * SeqList;
typedef int ReceType;
int Partition(SeqList R, int i, int j)
{//调用Partition(R, low, high)时, 对R[low..high]做划分,
//并返回基准记录的位置
ReceType pivot=R[i]; //用区间的第1个记录作为基准 '
while(i<j){ //从区间两端交替向中间扫描, 直至i=j为止
while(i<j&&R[j]<=pivot) //pivot相当于在位置i上
j--; //从右向左扫描, 查找第1个关键字小于pivot的记录R[j]
if(i<j) //表示找到的R[j]的关键字<pivot
R[i++]=R[j]; //相当于交换R[i]和R[j], 交换后i指针加1
while(i<j&&R[i]>=pivot) //pivot相当于在位置j上
i++; //从左向右扫描, 查找第1个关键字大于pivot的记录R[i]
if(i<j) //表示找到了R[i], 使R[i]>pivot
R[j--]=R[i]; //相当于交换R[i]和R[j], 交换后j指针减1
} //endwhile
R[i]=pivot; //基准记录已被最后定位
return i;
} //partition

void output(int x[], int n)
{
for (int i=0; i<n;i++)
{
printf("%d ", x[i]);
}
return;
}

/*找数组x中从from到to中子集的前k个最大值,并进行打印*/
void firstNLargeNums(int x[], int from, int to, int k)
{
if (k<=0) return;

int pos = Partition(x, from, to);
int len = pos - from +1; /*从from开始,到pos(含)的数的个数*/
if (len <= k)
{
output(x+from, len);/*输出这个数组从from开始的len个数(pivot及左边的数)*/
firstNLargeNums(x, pos+1, to, k-len);/*在pivot右边找剩下的k-len个最大的数*/
}else
{
firstNLargeNums(x, from, pos-1, k);/*否则, 在pivot左边找k个最大的数*/
}

}
/*测试用的主函数,用随机数发生器来产生数组*/
#define N 10
#define K 5
int main()
{
int *x = (int *) malloc(N*sizeof(int));
int i;
clock_t start,end;
double runtimelength;
start=clock(); /* 计时开始 */

/*产生随机N个整数构成的数组x*/
srand(time(NULL));
for (i=0;i<N;i++)
{
if(N>RAND_MAX) x[i] = (int)((double)rand() / RAND_MAX *N) ;
else x[i] = rand()%100;
}
if(N<20)
{
printf("原始数据:");
output(x, N);
}

printf("\n其中最大的%d个为:\n", K);
firstNLargeNums(x, 0, N-1, K);
end=clock(); /* 计时结束 */
printf("\n耗时:%6.1f 毫秒\n", runtimelength=(double)(end-start));

printf("\n");
free(x);
return 0;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-09-27
不用排序的做法,请LZ验证,确实代码有点复杂,希望有能人优化一下。
int main( void )
{
int a[100000];
int b[10];
int i=0;
int j=0;
int k=0; //记录一个检查点

//for( i=100000;i>=0;i-- )
for( i=0;i<100000;i++ )//先生成测试数据
a[i]=i+1 ;

for( i=0;i<10;i++ )//取前10个放入结果数组
b[i]=a[i];
//检查后续的数据,如果有数据大于结果数组中的数据,就换掉数组中的数据
//下一次检查从下一个数据检查到尾,再检查到当前位置,以保证每次都要检查10个数
//以避免后续的数总比第一个数大,就只会替换第一个数的情况。
for( i=10 ; i<100000 ; i++ )
{
while(j<10)
{
if ( b[j] < a[i] )
{
b[j]=a[i];
k=j; //记录下最后一个检查过的数
j++;
if ( j >= 10 ) j=0; //如果是最后一个数,则下次从0开始检查
break;
}
j++;
}
if ( j >= 10 )
{
j=0;
while( j<=k )
{
if ( b[j] < a[i] )
{
b[j]=a[i];
k=j;
j++;
break;
}
j++;
}
}
}
for(j=0;j<10;j++)
{
printf("%d\n" , b[j] );
}
return 0;
}
如果考虑排序,不如直接将100000个数据排序再取前10个!
第2个回答  2011-09-27
http://blog.csdn.net/aihahaheihei/article/details/6801847 这是我博客里的一篇文章,正是这个题目,里面有解释和完整的代码。用scanf(), printf() 比 cin, cout 的效率要高点,这题不能用cin,否则会超时。
第3个回答  2011-09-27
排列
一下哈
第4个回答  2011-09-27
什么语言?
实际上就是个排序的过程。追问

C++语言!求代码~~