01 二叉堆 | 二叉堆本质上是一种完全二叉树
- 二叉堆的根结点叫做堆顶。
1. 最大堆
- 最大堆任何一个父结点的值,都大于等于它左右孩子结点的值。
- 最大堆的堆顶是整个堆中的最大元素
2. 最小堆
- 最小堆任何一个父结点的值,都小于等于它左右孩子结点的值。
- 最小堆的堆顶是整个堆中的最小元素。
如何构建一个堆呢?
- 这就需要依靠二叉堆的自我调整。
堆的自我调整
对于二叉树,如下有几种操作:
- 插入结点
- 删除结点
- 构建二叉堆
02 举例:最小堆的自我调整
初始堆
插入数值举例
- 向初始堆中插入数值3时,首先在堆的末尾插入该数值,然后不断向上提升直到没有大小颠倒为止。
- 上浮
取出最小值举例
- 从堆中删除最小值时,首先把堆的最后一个节点的数值复制到根节点上,并且删除最后一个节点。然后不断向下交换直到没有大小颠倒为止。
- 下沉:在向下交换的过程中,如果有2个儿子,选择数值较小的儿子进行交换。
构建二叉树
- 构建二叉树,也就是把一个无序的完全二叉树调整为二叉堆,本质上就是让所有非叶子结点依次下沉。
堆的实现
- 二叉堆虽然是一棵完全二叉树,但它的存储方式并不是链式存储,而是顺序存储。 换句话说,二叉堆的所有结点都存储在数组当中。
堆操作的时间复杂度
- 堆的两种操作(插入、删除)所花的时间都和树的深度成正比。
- 如果一共有n个元素,那么每个操作可以在
O(logn)
的时间内完成。
03 堆的应用场景
- 堆排序
- 优先级队列
04 优先队列
满足操作:
- 插入一个数值
- 取出最小的数值(获得数值,并且删除)
实现:堆