堆,实际上是一个完全二叉树,大概就是介个样子。。。
堆一般又分为大顶堆和小顶堆(实际上差不多。。。这里就用小顶堆举个例好了QwQ)
手写堆
其实STL中的优先队列已经有堆的作用了,但是手写的堆也有一些自己的优势。我们先来看看堆的一些常用操作。
1.插入一个数
2.求集合当中的最小值
3.删除最小值
4.删除任意一个元素
5.更改任意一个元素
前三个功能,都可以通过优先队列直接实现,而后面两个功能,用手写的堆更容易实现,所以。。。手写的堆,也是有优势滴QwQ
手写的堆可以用一维数组存储,虽然看起来5个功能很麻烦,但其实依赖两个函数就可以全部实现。
利用down(下沉)函数和up(上升)函数,两个函数就可以实现上面的功能。
down函数
down函数主要是为了把大的数往树的下方沉,每次比较选择子节点中较小的一个数,进行替换,模板如下
void down(int u)
{
int t = u; // t 用于找一个最小的节点值
if(u * 2 <= size && h[t] > h[u * 2]) t = u * 2; // h 用于存放堆
if(u * 2 + 1