算法通关村14关 | 堆结构

1. 堆的概念与特征

堆是将一组数据按照完全二叉树的存储顺序,将数据存储在一维数组中的结构,对的结构有两种,一种称为大顶堆,一种称为小顶堆。

  • 小顶堆:任意节点的值均小于等于它的左右孩子,并且最小的值位于堆顶,即根节点处
  • 大顶堆:任意节点的值均大于等于它的左右孩子,并且最大的值位于堆顶,即根节点处

也可称为大根堆,小根堆,或者最大堆,最小堆,

假设一个节点的下标为i。

  1. 当i = 0时,为根节点。
  2. 当i >= 1时,父节点为(i - 1) / 2。

有些地方叫做堆,有些地方叫做队列,两者到底是什么关系?

优先队列:就是一种队列,它的工作是poll()/peek()出队列中最大、最小的那个元素,所以叫带有优先级的队列。能够实现优先功能的队列不一定只有堆,例如二项堆、平衡树、线段树、c++会用二进制分组的vector来实现一个优先队列。

堆:堆是一个很大的概念,他并不一定是完全二叉树,用完全二叉树是因为这个容易被数组存储,但除了二叉堆之外,我们还有二项堆,斐波那契堆,这种不属于二叉树。

2. 对的构造过程

使用数组构建堆,按照层次将所有元素依次填入二叉树中,使其成为二叉树,然后不断调整,使其最终符合堆结构。

将元素依次排列到完全二叉树上去,如下图所示。

  1. int i = (size - 2) / 2 = 4(思考一下这里为什么是size-2而不是size -1)。找到数组中的4号下标。65大于其孩子,满足最大堆性质,不用交换。
  2. 然后 i = i - 1;用2和其孩子比较,2和204交换。交换之后满足最大堆,如下图左
  3. 54和其孩子比较,54和92交换,92所在子树满足最大堆,如下图右。
  4. 23和其孩子比较,23和204交换,交换完之后,23的子树却不满足了,还需要调整其子树,如下两图
  5. 12和204交换,仍然出现不平衡情况,继续调整子树。直到根节点满足要求。

这样就建成了一个大顶堆,根元素是最大的那个

3. 插入操作

插入300,将其按顺序插入到31的右孩子位置,然后不断向上爬,31<300,所以两者交换,再向上发现300比65大,交换,300>204,交换,最后就是最新堆。

4. 删除操作

        堆中的数据特殊,对堆中数据进行的操作都是针对堆顶的元素,即每次从堆顶获取的最大值或最小值,其他的不关心,所以删除的时候,也是删除堆顶。删除堆顶整个结构会被破坏,需要再次调整。如果直接删除堆顶,群龙无首就不易管理了。实际策略是将队中的最后 一个元素与根元素交换,然后再删除堆的最后一个元素。之后再交换调最大堆,直到堆顶元素满足最大堆性质。

交换完成之后

关于堆的使用口诀

查找:找大用小,大的进;找小用大,小的进。

排序:升序用小,降序用大。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值