Skip to content
堆的性质
  • 堆是一种满足特定条件的完全二叉树 (小顶堆:任意节点的值 <= 其子节点的值;大顶堆:任意节点的值 >= 其子节点的值)
  • 最底层节点靠左填充,其他层节点都被填满(完全二叉树的性质)
  • 对于大顶堆(小顶堆),堆顶元素(根节点)的值是最大(最小)的

INFO

许多编程语言提供的是优先队列,堆通常用于实现优先队列,大顶堆相当于元素按从大到小的顺序出队的优先队列 从使用角度来看,可以将“优先队列”和“堆”看作等价的数据结构 在Java中可以认为堆就是优先级队列,优先级队列就是堆,其他语言不行。

DANGER

也有不属于完全二叉树的堆,比如二项堆、斐波那契堆

堆的操作
元素入堆

把新加的元素添加到堆底,【从底至顶】执行堆化

堆顶元素出堆
  • 交换堆顶元素和堆底元素
  • 删除堆底元素
  • 【从顶至底】执行堆化

WARNING

以下针对大顶堆(小顶堆符号反过来)

  • 【从底至顶堆化】
  1. 传入堆化节点的索引i
  2. 获取该节点i的父节点索引p
    2.1. 如果p<0,说明越过根节点了,堆化停止
    2.2. 如果当前节点的值 < 父的值,节点关系不用修复,堆化停止
  3. 否则,交换p节点和i节点的值
  4. 将i更新为p,向上继续堆化(为什么是向上?因为p是父节点索引)
  • 【从顶至底堆化】
  1. 传入堆化节点的索引i
  2. 获取左子节点索引l和右子节点索引r
  3. 找出l、r,i对应的值中最大的
  4. 如果最大的值是i对应的值,节点关系不用修复,堆化停止
  5. 否则,交换i节点和最大值节点的值
  6. 将i更新为最大值节点的索引,向下继续堆化(为什么是向下,因为i更新为子节点索引)
堆的使用技巧

查找:找(k)大用小(顶堆),(后序元素比根)大的进(堆);找小用大,小的进
排序:升序用小,降序用大

大顶堆代码示例

演示代码