BST:删除
看完你能独立处理三种BST删除情形,吃透每步树重连的原理
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
BST:删除
看完你能独立处理三种BST删除情形,吃透每步树重连的原理
删除节点的三种情况
从要删的节点出发,按子节点数量分三条路。
删除函数框架
把 BST 删除的完整骨架一次性摊开:外层递归负责定位,命中后按三种情况分别处理。
外层递归负责向下定位,命中后 `else` 块按「左空 / 右空 / 双儿」三路分支,把三种删除情况落到具体行。
叶子节点的删除
无子节点时直接断开连接
单子节点的删除
左右两棵子树分别是删除前与删除后,中间箭头标出核心操作。
单分支删除代码
三行代码同时搞定「单子节点」与「叶子节点」删除,关键在 NULL 子树的处理。
两段 if 同时覆盖「单子节点」与「叶子节点」删除:返回值可能是 None,父节点指针自然被改写。
后继节点是什么
前面搞定了叶子节点和单子节点两种情况。剩下最棘手的——左右孩子都在——要用到一个关键角色:后继节点。它到底是谁?为什么偏偏是它?
去高个子那队,再挑里面最矮的
后继节点位置
图示找到后继的路径
后继 vs 前驱
两种替换策略都能正确删除双子节点,学生常纠结「该用哪个」。其实它们完全对称。
- 找法:向右一步,再一路向左到底
- 形态:至多只有右孩子,没有左孩子
- 删除:从右子树把它真正删掉
- 找法:向左一步,再一路向右到底
- 形态:至多只有左孩子,没有右孩子
- 删除:从左子树把它真正删掉
双分支删除流程
双子节点删除拆三步:找后继、替换值、递归删后继。
双分支删除完整代码
完整 delete 函数:用 find_min 找后继,复制键值,再递归把后继从右子树删掉。
第19行确认命中目标;24–26行是双分支核心——找后继、覆盖键、递归删后继。后继没有左子,下次递归自然走单子分支退路,循环不会死。
删除的复杂度
前面三种删除情况都讲完了。现在问效率:双分支要沿树向下找后继——这条路径有多长?这取决于树的形状。
对半翻字典像平衡树 O(log n),逐字翻像斜树 O(n)
BST删除要点回顾
- ✓双分支本质是「替换值 + 删除后继」,最终都回到单子节点情况
- ✓替换值 ≠ 删除节点:必须把后继节点本身从原位置摘除
- ✓删除改的是父节点的指针,递归靠返回值把新子树根传回上层
- ✓复杂度即树高 h,平衡时 O(log n),链状时退化到 O(n)
- ✓后继默认选右子树最左节点,可保证 BST 仍有序
课后思考
先独立思考再看参考答案,看每条要点能想到几个。
参考答案后继一定没有左孩子,前驱一定没有右孩子,填补后仍满足左小右大。随便选会破坏BST有序性。
参考答案需约定重复值放左还是右子树。删除时按约定定位,或在节点维护计数器批量处理。
参考答案AVL/红黑树删除后还需旋转或变色恢复平衡。后继替换仍可复用,但平衡调整使其更复杂。