堆的删除模板
https://www.bilibili.com/video/BV19A411q7mn?t=1007
#include<iostream>
using namespace std;
/*先驱知识:结点i的的父节点序号是i/2(除了根节点)
结点i的左儿子序号是2*i,右儿子是2*i+1
(完全二叉树,可按照层序编号用数组储存) */
//堆的删除
//使用下沉法 把尾元素移到根上,向下逐层比较,下沉到合适的位置
//way1:交换法
int heap[200];
int len;
int DeleteMin()//取出并删除根元素(小根堆 最小值)
{
int pa, son;
int h = heap[1];//保存根元素
heap[1] = heap[len--];//尾元素移到根上,并且将尾部结点删除了
pa = 1, son=pa*2;//pa指向根结点,son指针指向左儿子
while (son <= len)
{
//注意上面len--了
if (son < len && heap[son + 1] < heap[son]) son++;//如右孩子小,则指向右孩子
if (heap[pa] <= heap[son]) break;
swap (heap[pa], heap[son]);//交换元素
pa = son, son = pa * 2;//下标下沉
}
return h;//返回根元素
}
//way2:上移法(效率更高)
int heap[200];
int len;
int DeleteMin()//取出并删除根元素(小根堆 最小值)
{
int pa, son;
int h = heap[1];//保存根元素
int t= heap[len--];//尾元素移到根上,并且将尾部结点删除了
pa = 1, son = pa * 2;//pa指向根结点,son指针指向左儿子
while (son <= len)
{
//注意上面len--了
if (son < len && heap[son + 1] < heap[son]) son++;//如右孩子小,则指向右孩子
if (t <= heap[son]) break;
heap[pa] = heap[son];//下面元素上移
pa = son, son = pa * 2;//下标下沉
}
heap[pa] = t;//插入尾元素
return h;//返回根元素
}
//堆的删除不适合用哨兵法