堆排序 & TopK

所有的完全二叉树都可以用数组来表示,但不一定都是堆,在这里堆使用一个数组来进行表示

存在数组中的完全二叉树通过孩子节点寻找父亲节点的方式

parent = (children-1)/2

大堆

树中的所有父亲节点都大于等于它的孩子节点

小堆

树中的所有父亲节点都小于等于它的孩子节点

添加节点

  1. 直接在尾i节点赋值
  2. 向上调整

删除根节点

  1. 将根节点与数组最后一个元素交换
  2. 然后向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{
	assert(a);
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (a[child - 1] < a[child])
		{
			child--;
		}
		if (a[child] < a[parent])
		{
			int temp = a[child];
			a[child] = a[parent];
			a[parent] = temp;
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void AdjustUp(HPDataType* a, int n)
{
	assert(a);
	int child = n - 1;
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child - 1] < a[child])
		{
			child--;
		}
		if (a[child] < a[parent])
		{
			int temp = a[child];
			a[child] = a[parent];
			a[parent] = temp;
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

堆排序

pop头结点,然后将结果打印

topK问题

N个数字,取到前K个最大的数

创建一个堆,大小为k,首先向堆内push数据,到达k个后停, 此时这k个数为数组前k个数字的最大的k个值,然后如果数据比堆的top大,直接覆盖top,然后向下调整

这样,堆内的数据不断更新调整,每次更新后都是已遍历的数据中最大的前k个数, 遍历结束后,再进行一遍堆排序,打印输出得到最终结果

该算法的空间复杂度:O(K)

该算法的时间复杂度:O(N*logK)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值