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

解法二用快速排序划分的方法

#include <iostream>
#include <time.h>
using namespace std;
const int K=5;
int Partition(int data[],int first,int end);
void K_Qsort(int data[],int first,int end,int dst[]);
void swap(int &a,int &b);
void main()
{
	int data[]={10,1,2,3,9,8,20,5,100,7,11,3};
	int dst[K];
	int length=sizeof(data)/sizeof(data[0]);
	K_Qsort(data,0,length-1,dst);
	for(int i=0;i<length;i++)
	{
		cout<<data[i]<<"\t";
	}
	cout<<endl;
	for(int i=0;i<K;i++)
	{
		cout<<dst[i]<<"\t";
	}
cout<<"end"<<endl;
}

/*data为待处理序列
 *first和end分别为数组的起始终止位置
 *dst为最终输出数组*/
void K_Qsort(int data[],int first,int end,int dst[])
{
	static int obtained=0;
	int need=K-obtained;
	if(need>0)
	{
	int mid=Partition(data,first,end);
	if( (end-mid)>need)
	{
		K_Qsort(data,mid+1,end,dst);
	}
	else
	{
		int M=mid+1;
		if( (end-mid)<need )/*在哨兵右侧还不够所需的数量,把哨兵也包含在内*/
		{
			M=mid;
		}
		for(int i=obtained,j=M;j<=end;i++,j++)
		{
			dst[i]=data[j];
		}
		obtained +=end-M+1;
		K_Qsort(data,first,mid-1,dst);
	}
	}
}

/*选择排序中的一次划分*/
int Partition(int data[],int first,int end)
{
	srand((unsigned)time(0));
	int ran=rand()%(end-first)+first;
	if(ran!=first)
	{swap(data[ran],data[first]);}/*随机值 若一直用第一个为哨兵可能已经是有序的,返回值一直不变*/
	int i=first;
	int j=end;
	while(i<j)
	{
		while(i<j && data[i]<=data[j])j--;
		if(i<j)
		{
			swap(data[i],data[j]);
			i++;
		}
		while(i<j && data[i]<=data[j])i++;
				if(i<j)
		{
			swap(data[i],data[j]);
			j--;
		}
	}
	return i;
}

void swap(int &a,int &b)
{
	int temp=a;
	a=b;
	b=temp;
}

 

解法四:用小根堆可以处理大数据,每次只需取入一个数据,可将其他数据先存于外存中

/*用小根堆方法取出最大的K个数
 *data待处理序列,datlen数组data的长度
 *dst 最终结果输出数组,datlen为数组长度,即K*/
void K_heapsmall(int data[],const int datlen,int dst[],const int dstlen)
{
	int cpynum=dstlen<datlen?dstlen:datlen;
	for(int i=0;i<cpynum;i++)
	{
		dst[i]=data[i];
	}
	if(datlen<=dstlen)
		return;
	else
	{
		for(int i=dstlen/2-1;i>=0;i--)/*构建小根堆*/
		{
			heapsmall(dst,i,dstlen);
		}
		for(int i=dstlen;i<datlen;i++)
		{
			if(data[i]>dst[0])
			{
				dst[0]=data[i];
				heapsmall(dst,0,dstlen);/*根结点值改变,进行堆调整*/
			}
		}
	}
}

/*小根堆
 *dst堆数组,node调整的结点,length数组的长度*/
void heapsmall(int dst[],int node, const int length)
{
	int i=node;
	int j=2*i+1;
	while( j<length)
	{
		if(j+1<length && dst[j]>dst[j+1]) ++j;
		if(dst[j]>=dst[i])
		{ break;}
		else
		{
			swap(dst[j],dst[i]);
			i=j;
			j=2*i+1;
		}
	}
}


 

你可能感兴趣的:(编程,DST)