文章目录
1.数据结构定义
建堆
堆是一个完全二叉树,用一维数组存堆,1号点是根节点左儿子2x,右儿子2x+1。
核心操作down和up
2.原子操作
求最值时间复杂度为 O ( 1 ) O(1) O(1),
up和down操作和树的高度有关,时间复杂度为 O ( l o g n ) O(logn) O(logn)
2.1.down操作
void down(int u)
{
int t=u;
if(u*2<=cnt&&h[u*2]<h[t]) t=u*2;//与左儿子比较
if(U*2+1<cnt&&h[u*2+1]<h[t]) t=u*2+1;//和右儿子比较
if(u!=t)
{
swap(h[u],t[t]);
down(t);//递归执行
}
}
2.2.up操作
void up(int u)
{
while(u/2&&h[u]<h[u/2])//和down操作恰好相反,down的边界是cnt,up的1边界是1
{
heap_swap(u,u/2);//down操作需要和左儿子和右儿子都作比较,up只需要比一个即可
u>>1;
}
}
2.3.heap_swap操作
void heap_swap(int a,int b)
{
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap(h[a],h[b]);
}
3.组合完成的操作
3.1.插入一个数
heap[++size] = x;up(size)
3.2.求集合中最小值heap[1]
heap[1]
3.3.删除最小值
heap[1]=heap[size];
size--;
down(1);
为了维护堆得结构
3.4.删除任意一个元素
heap[k]=heap[size];
size--;
down(k);
up(k);
为了维护堆得结构
3.5.修改任意一个元素
heap[k]=x;
down(k);
up(k);