定义
堆的表示
- 为了插入和删除的方便,我们将堆设计成一种特殊的二叉树:
- 在每一棵子树中,根结点最大。比如说我们每次要删的都是最大值,如果根结点不是最大,而是右结点最大,那么删除几次之后树都斜到左边了,这个树的高度就不是log2 n了。而根结点最大的话就能保持树一直是完全二叉树。
堆的操作
- 创建堆
- 这里是存放在数组中的
哨兵的作用后面再说
插入元素
- 首先插入最后一个位置,然后将其与根结点比较,若比根结点大则和根结点交换,再接着将其和更上一级根结点比较,还大的话再调换,知道不比根结点大为止。
- 进入循环之前,用i记录待插入元素,然后将其与根结点比较,若根结点小,则根结点会被挪到最后,再跟上上一级根结点比,根结点还是小,则会被挪到下一级根结点的位置上;若待插入元素比所有根结点大,则会放到哨兵的位置上。
算法实例:第五讲->5.1第2小节
删除元素
- 把5号赋给1号,然后删除5号
- 1号再跟它的子结点比较,小的话就和它交换位置,交换完了再和子结点比较,直到不小为止。
算法实例:第五讲->5.1第3小节
堆的创建
- 主要研究第二种方法
- 根据堆的删除算法,我们是先将根结点替换为最后一个结点,然后一个一个比较交换位置。这种算法的前提是,根结点的左右子树已经是堆了。利用这种算法来创建堆。
- 从底层第一个有儿子的结点87开始,它的左右必定已经是堆,然后利用堆的删除算法将其包括子树调整成堆;接着对前一个同级结点30也这么做。
- 时间复杂度是O(n).