编程之美 2.5 寻找最大的K个数

从一组无序的数中寻找最大的K个数。

方法一、递归。快排,两个部分,a,b。前一部分长度若>=K,则去前一部分中的前K个,否则后一部分再取K-length(a)个。

时间复杂度:O(N*logK)

方法二、转化为寻找K个数中最小的那个,即第K大的数。使用二分搜索策略。时间复杂度:O(N)。

方法三、使用堆排序。堆有K个元素,堆顶元素是K个元素中最小的。每当来一个数的时候,与堆顶判断,若小于堆顶,则不需要改变对结构,否则,替换堆顶,改变堆结构。时间复杂度O(N*logK)

方法四、使用计数排序、基排序,即对每个整数出现的次数做记录,从大到小取最大的K个。如果最大的数位max,最小为min,则把Max-min 分成M块,跨度为Max-min / M,时间复杂度:O((N+M)* logM (vmax-vmin)/d)

 

 方法三程序:

#include<iostream>
#include<time.h>
#define N 13 //取13个数字
#define d 2 //2位数字
#define K 4 //最大的4个数
using namespace std;
void MaxHeap(int num[],int i,int len)
{
	int temp;
	int larger=i;
	int left=2*i;
	int right=2*i+1;
	if (left<=len&&num[left]<num[i])
	{
		i=left;
	}
	if (right<=len&&num[right]<num[i])
	{
		i=right;
	}
	if (i!=larger)
	{
		temp=num[larger];
		num[larger]=num[i];
		num[i]=temp;
		MaxHeap(num,i,len);
	}
	
}
void BuildMaxHeap(int num[],int len)
{
	int i;
	i=len/2;
	while (i>=1)
	{
		MaxHeap(num,i,len);
		i--;
	}
}
void HeapSort(int num[],int len)
{ 
	int i;
	int temp;
	int j;
	BuildMaxHeap(num,len);
	j=len+1;
	while (j<=N)//每次更新堆
	{
		if (num[j]>num[1])
		{
			temp=num[1];
			num[1]=num[j];
			num[j]=temp;
			BuildMaxHeap(num,len);
		}
		j++;
	}
}
int main(int argc,char *argv[])
{ 
	int i;
	int temp=1; 
	int num[N+1];
	int len=N;
	srand((unsigned) time(NULL)); 
	for (i=0;i<d;i++) 
	{
		temp *= 10; 
	}
	for (i=1;i<=N;i++) 
	{ 
		num[i]=rand()%temp;
	}
	cout<<"排序之前数组中的数字为:"<<endl;
	for (i=1;i<=N;i++)
	{
		cout<<num[i]<<" "; 
	} 
	cout<<endl<<endl;
	HeapSort(num,K);
	cout<<endl<<"使用堆排序之后:"<<endl;
	for (i=1;i<=K;i++)
	{
		cout<<num[i]<<" "; 
	}
	cout<<endl;
	return 0;
}


 

你可能感兴趣的:(编程之美 2.5 寻找最大的K个数)