基础知识
- 小根堆(父节点的值大于子节点)
- 大根堆(相反)
- 节点在数组中下标为 i 时,左子节点为 2i+1,右子节点为 2i+2
堆的基本操作
这里以大根堆为例
- 上滤(插入新元素时)
- 从最后一个节点开始,向上比较,如果父节点小于此节点时,交换位置,直到比较失败,或到达顶端
- 下滤
- 从根节点开始,向下比较,其他和上面相反
如何构建堆
- 自顶向下构建
- 操作:遍历数组,尾部插入新元素,进行上滤操作
- 时间复杂度:O(nlogn),每个节点平均为logn/2,共有n个节点
- 自底向上构建
- 先对数组元素进行遍历操作,直接顺序构建堆
- 从数 n-1 深度开始,对此深度每个节点进行下滤操作,恢复子节点的堆序性,深度-1,重复此过程
- 时间复杂度为O(n),共n个节点,每个节点只需要和子节点这一层进行比较
堆的应用
- 优先队列
- 弹出最大元素(使用大根堆时,小根堆相反)
- 步骤:弹出根节点元素,将尾部元素放在根节点,进行下滤操作
- 由于要重构堆,加上下滤操作后,时间复杂度为 O(logn)
- 插入新元素
- 插入后进行上滤操作
- 弹出最大元素(使用大根堆时,小根堆相反)
堆排序
从小到大排序需要用大根堆,设数组长度为 n,i=n-1
- 将根节点与 i 换位置,这样第 i个元素就排好序了
- 排除已排好序的元素,对根节点进行下滤
- 重复 1,2,直到所有节点排好序