【算法通关村】原来这就是堆

堆的概念与特征

堆:将一组数据按照完全二叉树的存储顺序,将数据存储在一个一维数组中的结构。

堆分为大顶堆,小顶堆。

大顶堆:任意节点的值均大于等于它的左右孩子,并且最大值位于堆顶。

小顶堆:任意节点的值均小于等于它的左右孩子,并且最小值位于堆顶。

优先队列和堆不是同一个level的概念,但是Java的PriorityQueue就是堆实现的,因此在Java领域可以认为堆就是优先队列,优先队列就是堆,换做其他场景则不行。

堆的构造过程

如何建立一个大堆:

  1. int i = (size-2)/2 找到最后一个。

  2. 比较,比父节点大就交换。小则不动。

  3. i-1,继续比较。

  4. 若交换后,子树却不满足了,所以还需调整它的子树。

  5. 直到根节点也满足要求了,就完毕了。

插入操作

放到最后一个位置,然后上浮,保证子树都满足堆。

删除操作

堆本身比较特殊,一般对堆中的数据进行操作都是针对堆顶的元素。即每次都从堆中获得最大值或最小值,其他的不关心,所以我们删除的时候,也是删除堆顶。

如果直接删除堆顶,整个结构被破坏了。

实际策略,将堆最后一个元素和堆顶元素交换,然后删除堆中最后一个元素。然后再维持一下堆,上浮下沉。

总结

堆价值就在于大顶堆的根节点是整个树最大的那个,增加时会根据根的大小来决定要不要加,而删除操作只删除根元素。这个特征可以在很多场景下有奇妙的应用,后面的算法题全都基于这一点。

堆的效率高。因为堆元素的数量是有限制的,一般不用将所有的元素都放到堆里。后面题目中可以看到,在序列中找K大,则堆的大小就是K。如果K个链表合并,那么堆就是K。

口诀:

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

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

查找的方法就是:找 k 大, 则用小顶堆,后序的数据只有比根元素更大时才允许进入堆。如果找 k 小,则反过来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值