1. 概述

本文将介绍二叉搜索树(Binary Search Tree, BST)这种数据结构,重点讨论当节点中存储的键值为字符串时的应用场景与实现细节。

2. 简介

BST 是一种满足以下特性的二叉树:

  • 每个节点的左子树中所有节点的键值都小于该节点的键值;
  • 每个节点的右子树中所有节点的键值都大于该节点的键值;
  • 左右子树本身也必须是二叉搜索树。

在实际开发中,我们经常遇到键值为字符串的情况。这时,我们需要先定义字符串之间的比较规则。

字符串比较规则

我们使用字典序(Lexicographic Ordering)来比较两个字符串。具体做法是从左到右依次比较字符,遇到第一个不同的字符时,根据 Unicode 编码顺序决定大小关系。

例如:

  • "apple" < "orange" 因为 'a''o' 前面;
  • "Orange" > "orange" 因为大写字母 Unicode 编码小于小写;
  • "apple" == "apple" 因为所有字符都相同。

下图展示了两个字符串构成的二叉树:

bst with strings

左边是合法的 BST,右边不是,因为红色节点破坏了 BST 的性质。

3. 基本操作

BST 最常见的操作包括:插入、查找、删除。对于字符串类型的键值,核心在于如何正确进行字符串比较。

3.1 插入操作

插入逻辑如下:

  • 从根节点出发,向下查找插入位置;
  • 每次比较当前节点字符串与目标字符串,决定是进入左子树还是右子树;
  • 找到空位置后插入新节点。

插入伪代码如下:

algorithm BSTInsert(T, z):
    y <- null
    x <- T.root
    while x is not null:
        y <- x
        if z.key < x.key:
            x <- x.left
        else:
            x <- x.right

    z.parent <- y
    if y is null:
        T.root <- z
    else if z.key < y.key:
        y.left <- z
    else:
        y.right <- z

3.2 删除操作

删除操作较为复杂,分为三种情况:

情况一:节点没有子节点 → 直接删除
情况二:节点只有一个子节点 → 用子节点替换该节点
情况三:节点有两个子节点 → 找到其后继节点(右子树中最小节点)替换当前节点

删除伪代码如下:

algorithm BSTDelete(T, z):
    if z.left is null:
        TRANSPLANT(T, z, z.right)
    else if z.right is null:
        TRANSPLANT(T, z, z.left)
    else:
        y <- TREE-MINIMUM(z.right)
        if y.parent != z:
            TRANSPLANT(T, y, y.right)
            y.right <- z.right
            y.right.parent <- y
        TRANSPLANT(T, z, y)
        y.left <- z.left
        y.left.parent <- y

3.3 辅助函数 TRANSPLANT

TRANSPLANT 函数用于将一个子树替换另一个子树,是删除操作的核心部分。

algorithm TRANSPLANT(T, a, b):
    if a.parent is null:
        T.root <- b
    else if a = a.parent.left:
        a.parent.left <- b
    else:
        a.parent.right <- b

    if b is not null:
        b.parent <- a.parent

4. 时间复杂度分析

BST 中所有操作的时间复杂度均与树的高度有关。假设树高为 h,则各操作的时间复杂度如下:

操作 时间复杂度
查找 O(h)
插入 O(h)
删除 O(h)

⚠️ 注意:如果树退化为链表(例如插入顺序是有序的),则 h = n,此时时间复杂度变为 O(n)。为避免这种情况,通常会使用平衡树结构如 AVL 树、红黑树等。

5. 总结

本文介绍了在键值为字符串的情况下,如何使用二叉搜索树进行插入、查找和删除操作。核心在于理解字符串的比较规则(字典序)以及如何维护 BST 的结构。对于有经验的开发者来说,字符串 BST 是一个基础但实用的数据结构,尤其适用于字符串集合的有序管理场景。


原始标题:Binary Search Tree with Strings

» 下一篇: 汇编语言入门