1. 堆
1.1 定义
首先它是一颗完全二叉树,但是每个节点都要满足根节点的值大于子树中所有节点的值,就叫它大顶堆。如果每个节点的值都小于子树中所有节点的值,那么就叫小顶堆。
不是完全二叉树就不能是堆。
1.2 最最最基本的两个操作
up(x)
向上调整节点x到合适的位置。
down(x)
向下调整节点x到合适的位置。
其他的操作都由这两个最最最基本的操作组合完成。
1.3 插入
插到最后,然后up。
size++;
heap[size] = x;
up(size);
1.4 删除最值
删除最值的话,是固定的,每次都删除根节点root。
删除后,用整棵树的最后一个节点来代替它作为根节点,然后down根节点
heap[1] = headp[size];
size--;
down(1)
1.5 删除任意元素
heap[k] = heap[size];
down(k);
up(k);
// 此处虽然down和up都写了,但是实际情况中只会执行一个,1. 该点值大小变 2:变大 3:变小
1.6 建立
方法1:通过不断的插入。 时间复杂度为NlogN。N个节点插入N次,每次logN。
方法2:将所有元素先按顺序存入,先构成一颗完全二叉树。再调整各节点位置。时间复杂度是O(n)
采用方法2的过程如下:
先构造一颗完全二叉树,从最后一个节点的父节点开始,比如先调整87,然后调整30,然后调整83,然后调整43,然后调整66,然后调整79。,就完成了调整。
算法上的简单实现:
从n / 2一直down到根节点 1 即可,n为总的节点数。 n / 2 就是最后一个节点的父节点。
for(int i = n / 2; i; i--){
down(i);
}