堆,插入、删除、求堆顶
int pile[N];
int idx=1; // 下一个节点的位置
void exchange(int a,int b){
int temp=pile[a];
pile[a]=pile[b];
pile[b]=temp;
}
堆插入,以大根堆为例,完全二叉树,用数组存储
1、插入节点成为最后一个叶子节点,从该节点开始向上调整,每次只需要比较当前节点与父节点,看是否需要交换。因为大根堆的性质,父节点比左、右儿子节点都大,若当前节点比父节点大,则子树中当前节点最大。递归调整,代码如下。
void up_adjust(int a){
if(a>=2){
int pa=a/2;
if(pile[a]>pile[pa]){
exchange(a,pa);
up_adjust(pa);
}
}
}
2、删除根节点,将最后一个叶节点放到根节点处,递归向下调整,父节点与左、右儿子节点都要比较,代码如下:
void down_adjust(int pa){
if(2*pa<idx && 2*pa+1<idx){
if(pile[2*pa]>pile[2*pa+1]){
if(pile[2*pa]>pile[pa]){
exchange(pa,2*pa);
down_adjust(2*pa);
}
}
else{
if(pile[2*pa+1]>pile[pa]){
exchange(pa,2*pa+1);
down_adjust(2*pa+1);
}
}
}
if(2*pa<idx && 2*pa+1>=idx){
if(pile[2*pa]>pile[pa]){
exchange(pa,2*pa);
down_adjust(2*pa);
}
}
}