【概述】
堆(Heap),是一棵树,其每个结点都有一个值,且每个结点的值都大于等于或小于等于其父结点的值
当每个结点的值都大于等于其父结点的值时,称为大根堆;每个结点的值都小于等于其父结点的值时,称为小根堆
在 C++ 的 STL 中,优先队列 priority_queue 默认就是一个大根堆,在改写其比较算子 greater 后,可将其改为小根堆
一些功能强大的堆还支持可持久化,即对任意历史版本进行查询或操作,从而产生新的版本
【堆的分类】
常用的堆有二叉堆、配对堆、左偏树、二项堆、斐波那契堆等
下面以这些堆的小根堆为例,给出其基本操作的时间复杂度比较
| 操作 | 二叉堆 | 配对堆 | 左偏树 | 二项堆 | 斐波那契堆 |
|---|---|---|---|---|---|
| 插入 | $O(\log n)$ | $O(1)$ | $O(\log n)$ | $O(1)$ | $O(1)$ |
| 查询最小值 | $O(1)$ | $O(1)$ | $O(1)$ | $O(\log n)$ | $O(1)$ |
| 删除最小值 | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ |
| 合并 | $O(n)$ | $O(1)$ | $O(\log n)$ | $O(\log n)$ | $O(1)$ |
| 减小一个元素的值 | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ | $O(\log n)$ | $O(1)$ |
| 是否可持久化 | 是 | 否 | 是 | 是 | 否 |
习惯上,不加限定提到堆时往往都指二叉堆