递归中序遍历bst获取[low, high]区间值时,需根据节点值动态剪枝:val high则只递归左子树,仅在[low, high]内才递归左右子树,并用引用vector收集结果。

如何用递归中序遍历获取 BST 的 [low, high] 区间内所有值
二叉搜索树(BST)的中序遍历天然有序,所以最直接的方式是中序遍历整棵树,边遍历边收集 val >= low && val 的节点。但这样没利用 BST 的结构性质,最坏仍要访问全部节点。
真正高效的做法是「剪枝递归」:遇到 val 时,只往右子树走(左子树全更小);遇到 <code>val > high 时,只往左子树走(右子树全更大)。只有在 [low, high] 内才递归左右子树。
- 必须先判断当前节点是否在区间内,再决定子树访问方向
- 递归函数签名建议带引用参数
std::vector<int>& result</int>,避免频繁拷贝 - 注意边界包含性:题目若要求闭区间,就用
和 <code>>=,别写成或 <code>>
为什么不能直接用迭代中序 + break 提前退出
迭代中序(用栈模拟)确实能按序访问,但一旦遇到 val > high 就想 break —— 这不可靠。因为栈里可能还存着右子树的根,而该右子树的最小值(即其最左节点)可能仍 ≤ high。简单 break 会漏掉这部分。
真正安全的迭代写法必须配合剪枝逻辑,不是单纯“遍历到超限就停”:
- 每次 push 节点前,先检查该子树是否有进入区间的可能:若当前节点
val ,则左子树全无效,不 push 左;若 <code>val > high,则右子树全无效,不 push 右 - 栈中只保留「可能产出有效值」的路径节点
- 相比递归,迭代剪枝易多写几行,且可读性下降,除非有栈深度限制,否则优先用递归
当需要返回迭代器或支持流式查询时怎么处理
如果调用方希望「边查边用」而非一次性返回 vector(比如数据量大、或只取前 k 个),就不能把所有结果塞进容器。这时应封装为一个支持 next() 的迭代器类,内部用栈维护待访问节点。
关键点在于初始化栈时,从 root 出发,一路向左走到第一个 ≥ low 的节点(即下界 floor),途中只压入满足「该子树可能含有效值」的节点:
- 压栈前判断:若
node->val >= low,才压它;它的左子树是否要压,取决于node->left && node->left->val >= low - 每次
next()返回后,若该节点有右子树,则对其右子树执行「找第一个 ≥ low 的左链」并压栈 - 这种迭代器无法随机跳转,但空间复杂度稳定在 O(h),h 是树高
容易忽略的空指针和重复值场景
BST 定义通常允许「左子树 ≤ 根」或「左子树
常见疏忽点:
- 没判
root == nullptr直接访问root->val,导致段错误 - 把
low和high当作 int 传入,但实际可能是 long long(尤其 LeetCode 1239 风格题),比较时隐式转换出错 - 递归时误写成
if (val > high) return;却忘了继续处理左子树——正确逻辑是「只走左,不 return」
区间查询看着简单,真正写健壮要同时盯住结构特性、边界语义、空节点和类型安全。剪枝逻辑一旦写错一行,要么漏结果,要么多遍历,很难靠测试全覆盖发现。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











