AcWing算法基础课 堆
堆可以用二叉树存储。
当前节点比左右子节点的值都小或等于(小根堆)。
对于完全二叉树,根节点编号为1,则,对于编号为n的节点,左子节点编号为2n,右子节点标号为2n+1。
完全二叉树可以用一维数组存储(编号→下标)
基本操作:up和down
up:当节点数值比父节点小时,交换当前节点与父节点的值,然后递归。
down:当前节点数值比子节点大时,交换当前节点与较小的子节点的值,然后递归。
用于修改节点的值。
堆的操作:
1、插入一个数:在数组的末尾插入,然后进行up操作。heap[++size]=x; up(size);
2、求堆中最小值:返回第一个元素。heap[1];
3、删除最小值(堆顶元素),用数组中最后一个元素覆盖最小值,size--,然后进行down,heap[1]=heap[size]; size--; down(1);
4、删除任意元素,用数组中最后一个元素覆盖。heap[k]=heap[size]; up(k) or down(k) or not;
5、修改任意元素,然后调整。 heap[k]=x; up(k) or down(k) or not;
o(n)的快速建堆方式
在heap中读取全部元素
然后对n/2~1进行down()
for(int i=n/2;i;i--) down(i);
可以认为n/2后的节点位于叶节点位置,不需要down,其他的需要从下到上down()
带映射的堆:dijkstra算法中需要用
ph[k]记录第k个插入节点在数组中的位置,
hp[k]记录数组中第k个节点是第几个插入的,
ph与hp互为反函数
swap→heap_swap
void heap_swap(int a,int b)
{
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap[heap[a],heap[b]];
}

浙公网安备 33010602011771号