后继节点是bst中比当前节点值大的最小节点;有右子树时为其右子树最左节点,无右子树时为第一个作为左孩子的祖先,不带parent指针时可从根预存候选者实现o(h)时间复杂度。

后继节点是什么,为什么不能只靠中序遍历找
后继节点指在二叉搜索树(BST)中,比当前节点值大的最小节点。很多人第一反应是“跑一遍中序遍历,记录所有节点,再查下一个”——这在静态树里可行,但实际场景(比如在线查询、频繁插入删除)下,时间复杂度 O(n) 太重,且无法利用 BST 的结构优势。
真正高效的做法必须基于树结构本身,分两种情况处理:
- 如果节点有右子树,后继一定是右子树的最左节点;
- 如果没有右子树,则要向上回溯,找第一个“作为左孩子被访问”的祖先。
有右子树时怎么找最左节点
这是最简单也最常被写错的地方:不是直接返回 right,而是不断往左走到尽头。
- 从
node->right开始,循环判断是否非空,每次走current = current->left - 终止条件是
current->left == nullptr,此时current就是后继 - 注意边界:如果
node->right为空,这个分支根本不该进入
TreeNode* successor = node->right;
while (successor->left != nullptr) {
successor = successor->left;
}
无右子树时如何向上找“第一个左孩子祖先”
这个逻辑容易绕晕。核心是:从当前节点出发,沿着父指针往上走,直到某次是从左子树上来的(即当前节点是其父节点的左孩子),那个父节点就是后继。
- 需要节点结构包含
parent指针(否则无法实现O(h)时间) - 用循环判断
node == node->parent->right:如果是,说明当前节点是右孩子,继续向上;如果不是(即node == node->parent->left),就找到了 - 如果一路走到根都没找到,说明当前节点是整棵树最大值,无后继,返回
nullptr
TreeNode* parent = node->parent;
while (parent != nullptr && node == parent->right) {
node = parent;
parent = parent->parent;
}
return parent;
不带 parent 指针时还能做吗
能,但代价是每次查询都要从根开始模拟查找路径,时间仍是 O(h),不过空间变成 O(1)(不用递归栈或显式栈)。关键在于边找目标节点,边记录“可能的后继”。
- 初始化
successor = nullptr - 从根开始比较:若
root->val > target->val,更新successor = root,然后往左走;否则往右走 - 本质是把“向上找祖先”的过程,转化为“向下找过程中预存候选者”
- 这个版本不需要
parent字段,适合只读 BST 或无法修改节点结构的场景
最易忽略的一点:无论哪种实现,都默认树节点值互异,且满足 BST 性质。如果插入时没维护好左右关系,查出来的后继一定错——这不是算法问题,是数据前提崩了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











