1. 预备知识
(1) 基本概念
如图,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。树中的每一个结点对应数组中的一个元素。除了最底层外,该树是完全充满的,而且从左向右填充。堆的数组A包括两个属性:A.length给出了数组的长度;A.heap-size表示有多少个堆元素保存在该数组中(因为A中可能只有部分位置存放的是堆的有效元素)。
由于堆的这种特殊的结构,我们可以很容易根据一个结点的下标i计算出它的父节点、左孩子、右孩子的下标。计算公式如下:
parent(i) = i / 2;
left-child(i) = 2i;
right-child(i) = 2i + 1;
二叉堆通常可以分为两种形式:最大堆、最小堆。在这两种堆中,结点的值都要满足堆的性质。二者的差异在于:在最大堆中,除了根结点外的所有结点都要满足:
A[PARENT(i)]>=A[i],
最小堆相反。在用途上,最大堆通常用在堆排序算法中;最小堆通常用于构建优先队列。
我们定义堆中结点的高度为该结点到叶结点最长简单路径上边的数目。进而堆的高度定义为根结点的高度。
(2) 维护堆的性质
MAX-HEAPIFY函数的输入为一个数组A和一个下标i,它用来维护以下标i为根结点的子树最大堆的性质(这里假定以下标left(i)为根结点的子树和以下标为right(i)为根结点的子树满足最大堆的性质)。MAX-HEAPIFY的原理是通过让A[i]的值在最大堆中“逐级下降”,从而使得以下标i为结点的子树重新遵循最大堆的性质。