Top-K问题(堆的应用)

问题的引入:
我们都知道公司有所谓的世界500强,那么全球有如此多的公司,我们要怎样又快又精确的挑出这所谓的500家企业呢?

这就是所谓的 Top - K 问题 即求数据集合中前K个最大的元素或者最小的元素,一般情况下数据量都非常大。

对于该问题,我们能想到的最简单的直接方式就是排序,但是,如果数据量非常的大,排序就不太可取(可能数据都不能一下子全部加载到内存中)。最佳的方法就是用来解决,基本思路入下:

1. 用数据集合中前K个元素来建堆
2. 用剩余的 N-K个元素依次与堆顶的元素比较,不满足则替换堆顶元素。

在这里插入图片描述
附上代码:

void Top_K(int*a, int n , int k){
	int* kminHeap = (int*)malloc(sizeof(int) * k); //动态内存开辟创建数组
	for (int i = 0; i <k; i++)
	{
		kminHeap[i] = a[i]; //将前k个元素先放入数组中

	}

	for ( int j = (k-1-1)/2;  j>= 0; --j)
	{
		AdjustDown(kminHeap,k,j); //通过向下调整算法建堆

	}
	for (int i = k; i < n; i++)
	{    //和堆顶元素逐个比较并且满足条件进行替换,然后再进行向下调整算法!
		if (a[i] > kminHeap[0])
		{
			kminHeap[0] = a[i];
			AdjustDown(kminHeap, k, 0);

		}

	}
	for (int i = 0; i < k; i++)
	{ 
	    //打印前k元素
		printf("%d  ", kminHeap[i]);
	}


 }

同时附上向上调整和向下调整的算法:

void AdjustDown(HPDatatype* a, size_t size,size_t root) {
	size_t parent = root;
	size_t child = 2 * parent + 1;
	while (child < size) {
		if (a[child] >a[child +1] && child +1 < size)
		{
			++child;
		}

		if (a[parent] > a[child])
		{
			swap(&a[parent], &a[child]);
			parent = child;
			child = 2 * parent + 1;

		}
		else {
			break;
		}
    


	} 




}

void AdjustUp(HPDatatype * a, size_t child) {
	size_t parent = (child - 1) / 2;
	while (child > 0) {
		if (a[child] < a[parent]) {
			//交换
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;

		}
		else 
		{


			break;
		}
		

	}


}

Top-k问题在很多方面都有应用,在处理海量的数据时,Top-K算法能很快的帮我们确定我们要找的前k个最大元素!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值