当前:LC700 · 二叉搜索树中的搜索 · 首次出现于 Day 19 · 路径:顶栏「56天打卡」→ 点击 LC 题号 → 逐题动画

LC700 · Search in a BST · 树 / BST

BST 搜索:比较一次,丢掉一整边

左子树的值都比当前小,右子树都比当前大。target 只可能出现在其中一边,另一边连看都不用看。

从根出发:若 target 等于当前值返回该节点;小于则只查左子树;大于则只查右子树。BST 结构保证 target 只可能在一条分支上,所以每层比较都排除一半。递归或迭代均可。时间 O(h),空间 O(h)(递归)/ O(1)(迭代)。

时间 O(h)空间 O(h)结论先行 · 全文约 6 节
导读

给定一棵二叉搜索树的根和一个整数 val,返回值等于 val 的那个节点;找不到返回 null。返回的是节点指针,不是布尔,也不是下标。

主例树 [4, 2, 7, 1, 3],val = 5。根是 4,左挂 2(再挂 1、3),右挂 7。5 比 4 大、比 7 小,7 没有左孩子,答案是 null。演示路径 4→7,然后落空。

普通二叉树只能两边都搜。本文要回答:BST 多出来的那句「左边都小、右边都大」怎样把搜索收成一条折线,以及主例为什么在 7 的左侧停,而不去翻 2 那一侧。

Go:迭代搜索

solution.goGo
func searchBST(root *TreeNode, val int) *TreeNode {
for root != nil {
if root.Val == val { return root }
if val < root.Val { root = root.Left } else { root = root.Right }
}
return nil
}

1指针还在就继续比。主例第一轮 5≠4 且 5>4,root 改成 7。

2相等立刻返回当前节点,不要再往下走。

3循环走穿说明这条折线上没有 val。主例 7 的左是 nil,返回 nil。

总结

比大小只走一边。主例 5:4 右、7 左,落空。

  • BST 保证另一边不可能有 target。两边都搜是普通树,不是这题。
  • 迭代与递归同一条路径;迭代省栈。
  • 最坏退化链 O(n),平衡时 O(log n)。
同族题目
LC98验证二叉搜索树LC230二叉搜索树中第 K 小的元素LC235二叉搜索树的最近公共祖先