欢迎!输入数值体验 BST 的插入、搜索、删除操作

BST 的奇妙性质:中序遍历 = 有序序列

BST 性质:对任意节点,其左子树所有节点的值都小于该节点, 右子树所有节点的值都大于该节点。
因此按「左 → 根 → 右」顺序访问(中序遍历),输出的就是从小到大排序的序列!
点击按钮观看中序遍历如何产生有序序列

JavaScript 实现(BST 类)

// 节点结构
class Node {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

class BST {
    constructor() { this.root = null; }

    // 插入 - 平均 O(log n),最坏 O(n)
    insert(val) {
        const node = new Node(val);
        if (!this.root) { this.root = node; return; }
        let cur = this.root;
        while (true) {
            if (val < cur.val) {
                if (!cur.left) { cur.left = node; break; }
                cur = cur.left;
            } else if (val > cur.val) {
                if (!cur.right) { cur.right = node; break; }
                cur = cur.right;
            } else { break; }  // 重复值不插入
        }
    }

    // 搜索 - 平均 O(log n),最坏 O(n)
    search(val) {
        let cur = this.root;
        while (cur) {
            if (val === cur.val) return cur;
            cur = val < cur.val ? cur.left : cur.right;
        }
        return null;
    }

    // 删除 - 三种情况(叶子/单孩子/双孩子)
    remove(val) {
        this.root = this._remove(this.root, val);
    }

    _remove(node, val) {
        if (!node) return null;
        if (val < node.val) {
            node.left = this._remove(node.left, val);
        } else if (val > node.val) {
            node.right = this._remove(node.right, val);
        } else {
            // 情况1:叶子节点
            if (!node.left && !node.right) return null;
            // 情况2:只有一个孩子
            if (!node.left) return node.right;
            if (!node.right) return node.left;
            // 情况3:两个孩子 → 用中序后继替换
            let succ = node.right;
            while (succ.left) succ = succ.left;
            node.val = succ.val;
            node.right = this._remove(node.right, succ.val);
        }
        return node;
    }

    // 中序遍历 - O(n),输出有序序列
    inorder(node, out = []) {
        if (!node) return out;
        this.inorder(node.left, out);
        out.push(node.val);
        this.inorder(node.right, out);
        return out;
    }
}

时间复杂度分析

操作平均最坏说明
插入 InsertO(log n)O(n)树退化为链表时最坏
搜索 SearchO(log n)O(n)每次比较排除一半
删除 DeleteO(log n)O(n)先搜索再调整结构
中序遍历O(n)O(n)访问所有节点

实际应用场景

  • 🔍 有序集合:TreeSet / TreeMap 底层(红黑树是平衡BST)
  • 🗄️ 数据库索引:B+ 树是 BST 的进化版
  • 📊 范围查询:快速找到 [a, b] 区间的所有元素
  • 🎮 游戏排行榜:有序地维护玩家分数
  • ⚠️ 退化问题:顺序插入会退化为链表 → 需要 AVL/红黑树平衡