直接递归找min/max比遍历快,因BST结构性质保证最小值在最左末端、最大值在最右末端,只需O(h)单路径下降,无需O(n)遍历全树。

为什么直接递归找 min 或 max 比遍历快?
二叉搜索树(BST)的结构性质决定了:左子树所有节点值都小于根,右子树所有节点值都大于根。所以最小值一定在最左路径末端,最大值一定在最右路径末端——根本不需要访问其他分支。
递归只需沿单边下降,时间复杂度是 O(h)(h 为树高),而中序遍历找极值是 O(n)。平衡时前者是 O(log n),退化成链表时最坏也是 O(n),但实际写法上仍比遍历简洁、安全。
findMin() 递归实现的关键边界与空指针防护
递归终止条件必须严格处理空节点,否则会崩溃。常见错误是只检查当前节点非空,却忘了递归调用前没判空子树。
- 正确做法:若当前节点
root为空,直接返回空指针或抛异常(取决于接口设计) - 若
root->left为空,说明已到最左端,当前root就是最小节点 - 否则递归进入
root->left,不需额外比较值大小
示例(返回指针,假设节点结构为 struct TreeNode { int val; TreeNode* left; TreeNode* right; };):
立即学习“C++免费学习笔记(深入)”;
TreeNode* findMin(TreeNode* root) {
if (!root) return nullptr;
if (!root->left) return root;
return findMin(root->left);
}
findMax() 和 findMin() 的对称性陷阱
表面看只是把 left 换成 right,但容易在边界逻辑上出错。比如有人写成:
// ❌ 错误:没处理 root 为空,且递归调用未 guard
正确写法必须保持结构对称:
- 同样先判
!root - 再判
!root->right→ 此时root就是最大值 - 否则递归调用
findMax(root->right)
不要试图在递归后做值比较(如 max(root->val, findMax(root->right)->val)),这既低效又破坏 BST 结构优势。
迭代写法其实更安全,但递归更贴近思维直觉
递归代码短、易懂,但深度过大时有栈溢出风险(尤其退化树)。生产环境若树深度不可控,建议用迭代:
TreeNode* findMin(TreeNode* root) {
while (root && root->left) root = root->left;
return root;
}不过递归版本在教学、算法题、或明确控制树高(如 AVL/红黑树)场景下仍是首选。关键是:别混用递归和迭代逻辑,比如在递归函数里手动维护栈变量——那既没收益又难 debug。
真正容易被忽略的是:无论递归还是迭代,都依赖 BST 性质成立。如果树被非法修改过(比如插入没维护 BST 规则),findMin 可能返回错误结果,且这种错误不会报错,只会静默失效。


















