数据结构和算法:建立topK(大顶堆或小顶堆)

建立topK是基于堆排序变化而来的,我们建立topK是因为海量数据(正整数)按逆序排序排列的前k个数(topK),因为数据量太大,不能全部存放进内存中,我们只能存进一下部分,但是我现在就想找到前k个最小的数存进我们的空间之中,我们应该怎么办?

不建立堆的话,我们也是有办法的,可以先进行排序,我们再找到前k个元素存放进我们的空间中,但是我们这次用堆的形式来实现

我们来说一说思路(以小顶堆为例):1.我们用nums来存放数据,同时建立一个存放k个元素的容器heap来存放nums的前k个元素

2.我们将heap的元素建立一个大堆,建堆的过程在我的博客排序(上)详细的讲到过,然后我们将nums中k以后的元素和这个堆顶来比较,因为堆顶是这个堆中最大的元素,只要小于堆顶就有资格进入我们的堆,我们将堆顶和nums对应的元素交换

3.然后我们向下调整,更新堆,让最大的再次到达根节点的地方

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//向下调整算法,建立一个小堆
void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
vector<int> Ajustdown(vector<int>heap, int k, int pos)
{//建立一个大堆
	int parent = pos;
	int child = 2 * parent + 1;
	while (child < k)
	{
		if (child+1<k && heap[child]<heap[child + 1])//找到孩子中较大的一个孩子
		{
			child = child + 1;
		}
		if (heap[parent] > heap[child])//和父节点比较哪个更大
		{
			break;
		}
		else {
			Swap(&heap[parent], &heap[child]);//如果父亲比孩子要大,交换父节点和孩子的值
			parent = child;
			child = parent * 2 + 1;
		}
	}
	return heap;
}
void creat_heap(vector<int>& heap, int k)
{//建立一个大堆
	int parent = (k - 1 - 1) / 2;
	for (int i = parent; i >= 0; i--)
	{
		heap = Ajustdown(heap, k, i);
	}
}
int main()
{
	int k = 5;//表示heap这个空间只能存放5个元素
	vector<int>nums = { 12,52,78,59,46,49,65,42,15,34,28,9,5 };
	vector<int>heap(k, 0);//给heap的空间进行初始化的操作
	for (int i = 0; i < k; i++)//将nums数组中前个值存放到heap当中
	{
		heap[i] = nums[i];
	}
	creat_heap(heap, k);//建立一大堆
	for (int i = 0; i < heap.size(); i++)//遍历我们建立好的堆
	{
		cout << heap[i] << " ";
	}
	cout << endl;
	for (int i = k; i < nums.size(); i++)//因为我们建立的是大堆,根节点就是最大的一个数
	{
		if (nums[i] < heap[0])//找到一个比根节点小的,代替他
		{
			heap[0] = nums[i];
			heap = Ajustdown(heap, k, 0);
		}
	}
	for (int i = 0; i < heap.size(); i++)
	{
		cout << heap[i] << " ";
	}
	cout << endl;
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值