完全二叉堆:删除与下滤
看完你能亲手画出一个元素出堆后的下滤全过程
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
完全二叉堆:删除与下滤
看完你能亲手画出一个元素出堆后的下滤全过程
删除的真正难题
上页说过:堆顶是最值,取走它天经地义。但取走后堆顶空出一个洞,谁来补?随手挑一个放上去,堆序和完全二叉树的形状可能同时崩掉。
让最基层的新人直接当总经理(上移)会乱套,得选够格者接位再逐级调整
下滤算法四步法
删除堆顶后,用固定四步把新顶沉到正确位置,恢复堆序。
为什么选「较大的孩子」交换
上一页的下滤四步法里藏着一个关键选择:换哪个孩子?选错了,堆性质照样被破坏。这一页把所有选项摆上台面,看看为什么只有一个答案是安全的。
新队长必须压住两边所有人,所以只能选最强者上场
删除前的堆全貌
这是一棵已建好的小节堆:树形与数组两种视角并存,先认清堆顶与末元,后面删除操作全围绕它们展开。
下滤执行全程图解
以实际堆为例:删除最大元 50 后,末元 10 逐层下滤的全过程。
提前终止的边界
这张流程图展示下滤走到叶子边界的判断路径:每层先确认孩子是否存在,只比较真实存在的孩子。
percolateDown 实现
循环节三步:找较大的孩子、比较决定是否交换、下移一层继续。
循环节完整对应「四步法」:算孩子下标→选较大孩子→不满足则交换→游标下移进入下一轮;两个 break 分别覆盖越界与提前终止两类边界。
delMax 主函数实现
delMax 三步组合:摘顶、末元补位、缩减规模后调下滤,看主流程如何串起前面的算法。
四步各占一行:摘顶保返回值、末元补位破坏堆序、缩减规模、下滤修复——正是本节标题的组合逻辑。
实现中的陷阱辨析
前面已经跑通了 delMax 和 percolateDown 的完整代码,但「能跑对」和「写得稳」是两回事。这页把实现中最常踩的三个坑摆在一起,逐一辨析,帮你把代码的每个分支都变得有据可依。
楼梯只剩一级时不能再跨两步,对应右孩子不存在时的判断
为什么是 O(logn)
前面图解里,下滤每一步只沿着一条路径往下走。直觉上走得不远,但深入分析要给出证明:这条路最长能有多长?答案藏在完全二叉树的形状里。
报告每下一级只和一个主管交涉,层级数就是审批时间
插入上滤 vs 删除下滤
上滤与下滤方向相反、比较对象不同,初学最易混为一谈,值得逐条对齐辨析。
- 方向:自底向上,向堆顶移动
- 比较对象:只和父亲比
- 场景:新元素入堆后的修复
- 方向:自顶向下,向叶层移动
- 比较对象:和较大的孩子比
- 场景:摘走堆顶后的修复
自测:下滤走几步
在含 1000 个元素的完全二叉堆中删除最大值,最坏情况下下滤需要交换多少次?
要点回顾
- ✓删除=末元素补顶+下滤复位
- ✓每层与较大孩子交换,直到不再下沉
- ✓到达叶子或无更大孩子即可提前终止
- ✓树高 O(logn),故删除为 O(logn)
- ✓上滤比父、下滤比子,方向成对
课后思考
先合上讲义自己想,再对照参考答案,看思路是否一致。
参考答案倒序保证做下滤时左右子树已是合法堆,四步法的前提才成立;若从根开始,子树还未成堆,下滤无从比较。小堆先立,大堆再合。
参考答案与较小孩子交换后,较小的孩子升上来,可能仍大于另一侧被换下去的孩子的孩子,堆序在跨层处断裂。可试 9、8、7 的堆删 9,换 7 后 8 在 7 之下。
参考答案换来插入与删除的 O(logn),却牺牲了全局次序:找中位数、第 k 小、范围查询都得扫全堆。只要最值,堆最省;要更多次序,得换数据结构。