BST删除节点本质是通过指针重组维持有序性,分三类:叶子节点直接断开父指针;单子节点由父节点接管其子树;双子节点用中序后继值替换后递归删除后继。
二叉搜索树(bst)中删除节点的本质,不是单纯“删掉一个内存块”,而是通过指针重组维持整棵树的有序结构。关键在于:目标节点被移除后,它的父节点、子节点之间的引用关系必须重新建立,且不能破坏“左小右大”的性质。这三种场景的指针变换逻辑,其实对应着三种家庭结构——没孩子、一个孩子、两个孩子。
叶子节点:断开即完成
叶子节点没有子节点,所以它在树中只承担“被指向”的角色,不负责指向别人。删除时只需让它的父节点把对应方向(left 或 right)的指针设为 null 即可。
- 先定位目标节点及其父节点(可通过递归路径自然获得)
- 判断目标是父节点的左子还是右子
- 将父节点的对应指针置空,例如 parent->right = nullptr
- 最后释放该节点内存(C/C++需手动 free 或 delete)
单子节点:子树直接上位
这类节点只有一个孩子,删掉它后,它的孩子就“失去上级”,必须由它的父节点直接接管。相当于把一段链路从“父→目标→子”压缩成“父→子”。
- 若目标节点只有左子节点,则令 parent->left = target->left(或 parent->right = target->left,依父子方位而定)
- 若只有右子节点,同理替换为 target->right
- 注意:操作前保存子节点指针,再释放 target,避免悬空访问
双子节点:值替换 + 后继递归删
这是唯一不能直接断开指针的场景。因为删掉它会同时丢失左右两棵子树的连接入口。标准解法是用它的中序后继(右子树最左节点)或中序前驱(左子树最右节点)来“顶替”其值,再删除那个后继/前驱节点——而那个节点必然是叶子或单子节点,回到前两种情况。
- 找到右子树最小节点(沿 right→left→left… 走到底)
- 将该最小节点的值复制到目标节点(target->val = successor->val)
- 在右子树中递归删除这个最小节点(此时它已是叶子或单子,触发前两类逻辑)
- 整个过程不改变原树拓扑结构,只调整值和局部指针
指针重组不是靠记忆模板,而是理解每个节点在有序约束下的“不可替代性”。只要始终围绕“谁该连谁、为什么必须这么连”,三种场景的变换就自然浮现。










