Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

二叉搜索树 (BST)

| , 2 minutes reading.

二叉搜索树:双刃剑

算法背后的故事:岔路口

想象你站在一个岔路口。路标上写着一个数字,比如 50

  • 你正在寻找 30 号房子。
  • 路标上写着:“较小的数字走左边。较大的数字走右边。”

于是你向左走。你遇到了另一个岔路口,上面写着 25

  • 30 比 25 大。你向右走。
  • 你到达了 30 号房子。

这就是 二叉搜索树 (BST)。它将“搜索”这一行为转化为一系列简单的 是/否 决策。你不需要走过 1000 栋房子,你只需要做大约 10 次决定。

为什么需要它?

BST 是以下技术的理论基础:

  • 数据库: 如何在不扫描整张表的情况下找到一个用户 ID?
  • Set/Map: 以有序的方式存储唯一项。
  • 自动补全: 虽然 Trie 更好,但 BST 可以处理范围查询,如“找出所有年龄 > 18 且 < 25 的用户”。

算法是如何“思考”的

这个算法是一个守门人

  1. 搜索: 将目标与当前节点比较。如果小,向左。如果大,向右。如果相等,找到了。
  2. 插入: 搜索直到你撞上死胡同 (None)。把新节点放在那里。
  3. 删除: 最棘手的部分。
    • 如果是叶子:直接剪掉。
    • 如果有一个孩子:让孩子接班。
    • 如果有两个孩子:找到“继承人”(右子树中最小的节点),用它替换目标,然后删除那个继承人。

工程决策:致命缺陷

BST 有一个阿基里斯之踵:输入顺序

  • 场景 A (随机): 你插入 [5, 3, 7, 2, 4]。树很茂盛且平衡。高度约为 logN\log N。搜索很快。
  • 场景 B (有序): 你插入 [1, 2, 3, 4, 5]。
    • 1 成为根。
    • 2 跑到 1 的右边。
    • 3 跑到 2 的右边。
    • … 这棵树变成了一条线。高度是 NN。搜索很慢 (O(N)O(N))。

这就是为什么原始 BST 在生产环境中很少使用。我们使用它们更聪明的表亲:AVL红黑树

实现参考 (Python)

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def insert(root, val):
    if not root:
        return TreeNode(val)
    if val < root.val:
        root.left = insert(root.left, val)
    elif val > root.val:
        root.right = insert(root.right, val)
    return root

def search(root, val):
    if not root or root.val == val:
        return root
    if val < root.val:
        return search(root.left, val)
    return search(root.right, val)

# 使用示例
root = None
values = [50, 30, 20, 40, 70, 60, 80]
for v in values:
    root = insert(root, v)

result = search(root, 60)
print(f"找到: {result.val if result else 'None'}")

小结

BST 教会我们:结构取决于历史。如果数据以良好的顺序到达,结构就很坚固。如果数据以糟糕的顺序到达,结构就会崩塌。它提醒我们,在工程中,我们不能依赖运气;我们需要机制(平衡)来强制执行秩序,无论外界多么混乱。