20170927_利用大根堆求出最小的K个数

20170927_利用大根堆求出最小的K个数


当数据量比较大而内存一次性装不下的时候,想要对求出数据中最小的K个数,
则可以采用大根堆,维护一个含有K个数的大根堆,这个堆中的所有元素就是所求。
首先,读入K个数创建一个大小为K的大根堆,然后依次读入后序的数据,依次与大根堆的堆顶元素比较,
若大于堆顶元素,则直接抛弃该元素、读入下一个元素。
若小于堆顶元素,则该元素属于最小的K个元素之一,需要用它来替换堆顶元素,然后再从堆顶元素开始维护这个大根堆。
直到所有元素都比较完为止,这个堆中的所有元素就是所求。


//大根堆的应用_数组中查找最小的K个数
/*
当数据量比较大而内存一次性装不下的时候,想要对求出数据中最小的K个数,
则可以采用大根堆,维护一个含有K个数的大根堆,这个堆中的所有元素就是所求。
首先,读入K个数创建一个大小为K的大根堆,然后依次读入后序的数据,依次与大根堆的堆顶元素比较,
若大于堆顶元素,则直接抛弃该元素、读入下一个元素。
若小于堆顶元素,则该元素属于最小的K个元素之一,需要用它来替换堆顶元素,然后再从堆顶元素开始维护这个大根堆。
直到所有元素都比较完为止,这个堆中的所有元素就是所求。
*/

#include
#include
#include
#include
#include
#include
using namespace std;
//建立大根堆——>自上而下的重新调整堆结构
void Sift(int r[], int k, int m)
{
	int i=k;		//需要调整的节点是k=i
	int j=2*i;		//节点j 是节点i 的左孩子节点
	int temp=0;		//堆中最后一个结点的编号是m(m=n),节点总个数
	while(j<=m)		//筛选还没有进行最后一个节点时
	{
		if(jr[j])				//如果根节点i值已经大于左右孩子中的最大值,直接退出即可
			break;
		else						//否则,需要交换根节点和左右孩子中的最大值的那个节点
		{
			temp=r[i];
			r[i]=r[j];
			r[j]=temp;
			i=j;					//被筛节点位于原来节点j的位置
			j=2*i;					//自上向下调整,i始终是被筛的节点
		}
	}
}
//建立大根堆——>循环建立
void CreatBigHeap(int r[], int n)
{
	for(int i=n/2; i>=1; --i)		//共n个元素,从最后一个非叶子节点开始筛
		Sift(r, i, n);				//每次筛的节点是i
}
//主函数
int main(void)
{
	int k=0;
	cin>>k;							//最小的K个数
	int r[]={1,2,8,7,3,4,6,5};
	int *B=new int(k);
	for(int i=0; i=B[i])			//若大于堆顶元素
			continue;
		else					//若小于堆顶元素
		{
			B[i]=r[i];
			Sift(B, 1, k);
		}
	}
	system("pause");
	return 0;
}


你可能感兴趣的:(C++剑指offer)