堆-优先级队列和海量数据top K问题

在100亿个数中找出最大的前k个数(海量数据Top k问题),100亿啊,怎么找都觉得占空间很大啊,按一个数四个字节算,那也得40g啊,那得用堆的方法来做。                                                                                                                                           如何建立一个堆戳链接 点击打开链接

首先把前k个数构建成一个小堆,这样第一个数a[0]永远是这前k个数中最小的,从第k个数开始,每一个数和a[0]做比较,如果比a[0]大的话,它们两个一换,然后再将这个堆重新调整成一个小堆,继续用a[0]和第k+1的数进行比较,以此类推,一直到这些数轮完,那么这个堆里的这k个数就是这100亿个数中最大的了(其中涉及到向下向上调整都在之前如何建立堆里,戳上面的链接)

void TopK(DataType* a, size_t n, size_t k)
{
	int i;
	MakeHeap(a, k);//小堆
	for (i = k; i < n; ++i)
	{
		if (a[i]>a[0])
		{
			DataType tmp = a[0];
			a[0] = a[i];
			a[i] = tmp;
			AdjustDown(a, k, 0);
		}
	}
	for (i = 0; i < k; ++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}
优先队列是允许至少下列两种操作的数据结构:允许找出、返回和删除优先队列中最小的元素。下面是堆得实现
#define N 1000

typedef struct PriorityQueue
{
	DataType _a[N];
	size_t _size;
}PriorityQueue;
void PriorityQueueInit(PriorityQueue* q)//初始化
{
	assert(q);
	q->_size = 0;
	memset(q->_a, 0, sizeof(DataType)*N);
}
void PriorityQueuePush(PriorityQueue* q, DataType x)//入队
{
	assert(q);
	if (q->_size >= N)
	{
		printf("PriorityQueue full\n");
		return;
	}
	q->_a[q->_size++] = x;
	AdjustUp(q->_a, q->_size, q->_size - 1);
}
void PriorityQueuePop(PriorityQueue* q)//出队
{
	assert(q);
	if (NULL == q)
	{
		printf("PriorityQueue empty\n");
		return;
	}
	q->_a[0] = q->_a[q->_size - 1];
	q->_size--;
	AdjustDown(q->_a, q->_size, 0);
}
DataType PriorityQueueTop(PriorityQueue* q)//取栈顶元素
{
	assert(q);
	if (NULL == q)
	{
		printf("PriorityQueue empty\n");
		return;
	}
	return q->_a[0];
}
size_t PriorityQueueSzie(PriorityQueue* q)//求队列元素个数
{
	assert(q);
	return q->_size;
}
size_t PriorityQueueEmpty(PriorityQueue* q)//求剩余元素个数
{
	assert(q);
	return q->_size;
}
如果有不对的地方,可以评论告诉我,望指导!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值