堆の学习笔记
前言
关于这篇文章其实已经咕了
现在终于打算动了。
正文
首先堆是什么?
堆是一种数据结构,可以高效地以
这种数据结构在一定程度上借助完全二叉树实现,整体的实现思路是将堆抽象成一棵完全二叉树,然后根据完全二叉树的特性巧妙地维护最值。
这里附张图(搬运):
如果将完全二叉树的节点按上到下的次序标数,于是我们便可以大搞特搞于是可以用一个数组
然后为了方便维护最值(这里维护最小值)我们可以给堆加性质:
-
堆的任意父亲点
左儿子和右儿子。 -
堆必须时刻是完全二叉树。
这时最上面的根点一定是整个堆中最小的,我们只要不断维护堆的形态使性质成立,那么就很容易取到最小值。
Del 操作(删除最值):
最值一定是根点,所以我们只要删掉根点就行了。
假设这是原先的堆:
现在我们删除根点,很显然直接拿掉会让堆乱套,为了维护堆,我们只能把
之后把
给出核心代码(ok 是最后一个点的位置):
void del(){
swap(d[1],d[ok]);//交换
ok--;//删除
int dq=1;
while((dq<<1)<=ok){//如果当前点还有儿子
int nex=dq<<1;
if(nex+1<=ok&&d[nex+1]<d[nex]) nex++;//此时nex为值小的儿子的编号
if(d[nex]<d[dq]) swap(d[nex],d[dq]);
else break;//如果不用交换了直接退出
dq=nex;
}
}
ins操作(插入任意值):
和上面类似,但这次是在最下面建新的点,然后往上调整。图可以自行脑补就不放了。
核心代码:
void ins(int x){
d[++ok]=x;//新建
int dq=ok;
while(dq){
int fa=dq>>1;//父亲点i(因为儿子是父亲的2i或者2i+1,整除后一定会得到i)
if(d[fa]>d[dq]) swap(d[fa],d[dq]);
else break;//如果不用调整了退出
dq=fa;
}
}
查询最值:
只要输出根点
模板题:P3378。
附习题:
P1090
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧