二叉堆是一种特殊的二叉树,满足两个条件:
1 二叉堆完全平衡,就是说除了最底层,上面都完全填满
2 二叉堆节点有序,对于每一个父节点都大于等于子节点。
尽管书上一般用图表示二叉堆,但是在计算机里实现二叉堆并不需要真正构造节点和边,而是构造一个数组,每个元素代表节点,而索引之间代数关系代表链接。
二叉堆的性质:
1 a[1](根节点)为最大值
// 注意一般取a[1]而非a[0]为根,以简便运算
2 使用数组索引在堆上移动:
对于k索引节点: 父节点 k / 2
子节点2k 2k + 1
二叉堆操作:
1 上浮
如果二叉堆中一个子节点大于了父节点,重复将该子节点和其父节点交换,直到满足子节点小于父节点或者达到根
private void swim(int k) {
while (k > 1 && less(pq[k / 2], pq[k])) {
exch(pq, k / 2, k); // switch the node with father
k /= 2; // new position of k
}
}
利用swim方法我们可以实现在堆里插入新元素。首先把该元素放到堆末尾,然后使用swim将其归位
private void insert(Key v) {
N++;
pq[N] = v;
swim(N);
}
2下沉
如果二叉堆一个父节点小于了子节点,重复将该节点和其最大的子节点交换,直到满足父节点大于子节点或达到堆底
private void sink(int k) {
while (k * 2 <= N) {
int j = 2 * k;
if (j < N &&