二叉搜索树:高效增删查的秘诀

一、二叉搜索树 BST 定义

二叉搜索树(Binary Search Tree)满足核心规则:

  1. 左子树所有节点值 < 根节点值
  2. 右子树所有节点值 > 根节点值
  3. 左右子树也同样满足以上规则

关键特性:BST 中序遍历结果 = 升序有序数组

二、节点结构

和普通二叉树节点完全一致:

复制代码
struct TreeNode
{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

三、BST 查找操作

思路

  • 比当前节点小 → 去左子树
  • 比当前节点大 → 去右子树
  • 相等 → 找到
  • 走到空 → 不存在

cpp

运行

复制代码
// 递归查找
TreeNode* searchBST(TreeNode* root, int val)
{
    if(!root || root->val == val)
        return root;

    if(val < root->val)
        return searchBST(root->left, val);
    else
        return searchBST(root->right, val);
}

四、BST 插入操作

思路

按大小找位置,遇到空节点直接新建节点挂上。

复制代码
TreeNode* insertBST(TreeNode* root, int val)
{
    // 找到空位置,新建节点
    if(!root)
        return new TreeNode(val);

    if(val < root->val)
        root->left = insertBST(root->left, val);
    else if(val > root->val)
        root->right = insertBST(root->right, val);
    
    // 相等不插入
    return root;
}

五、BST 删除操作(面试重点)

分三种情况:

  1. 叶子节点:直接删除

  2. 只有左 / 只有右子树:用子树顶替自己

  3. 左右都有子树 :找右子树最小值左子树最大值 替换,再删替补节点

    // 找右子树最小值节点
    TreeNode* getMin(TreeNode* root)
    {
    while(root->left)
    root = root->left;
    return root;
    }

    TreeNode* deleteBST(TreeNode* root, int val)
    {
    if(!root) return nullptr;

    复制代码
     if(val < root->val)
     {
         root->left = deleteBST(root->left, val);
     }
     else if(val > root->val)
     {
         root->right = deleteBST(root->right, val);
     }
     else
     {
         // 情况1:叶子 / 只有单孩子
         if(!root->left) return root->right;
         if(!root->right) return root->left;
    
         // 情况2:左右都有孩子,拿右子树最小值顶替
         TreeNode* minNode = getMin(root->right);
         root->val = minNode->val;
         root->right = deleteBST(root->right, minNode->val);
     }
     return root;

    }

六、中序遍历验证有序性

cpp

运行

复制代码
void inOrder(TreeNode* root)
{
    if(!root) return;
    inOrder(root->left);
    cout << root->val << " ";
    inOrder(root->right);
}

七、完整测试代码

复制代码
#include <iostream>
using namespace std;

// 复制上面节点、查找、插入、删除、中序遍历函数

int main()
{
    TreeNode* root = nullptr;
    // 插入构建BST
    root = insertBST(root,5);
    insertBST(root,3);
    insertBST(root,7);
    insertBST(root,2);
    insertBST(root,4);

    cout << "BST中序遍历(升序):";
    inOrder(root);
    cout << endl;

    // 删除节点3
    root = deleteBST(root,3);
    cout << "删除3后中序遍历:";
    inOrder(root);

    return 0;
}

八、BST 适用场景

  1. 自动排序、有序数据维护
  2. 高效查找、插入、删除 O (logn)
  3. C++ map /set 底层基于红黑树(平衡 BST)
  4. 笔试面试常考手写 BST 增删查

九、易错点总结

  1. 忽略 BST 左小右大规则
  2. 删除左右都有子树的节点不会找替补节点
  3. 插入重复值不做判断,破坏 BST 结构
  4. 忘记中序遍历一定升序这个特性

十、今日总结

  1. BST 核心规则:左小右大
  2. 中序遍历天然升序
  3. 掌握查找、插入、删除三套递归模板
  4. 删除三种情况是面试高频考点,必须熟练
相关推荐
青云计划1 小时前
Spring
java·后端·spring
米啦啦.1 小时前
STL(标准模板库)
开发语言·c++·stl
yychen_java1 小时前
深度解析电力交易系统的“硬核”战场
java·能源
无敌昊哥战神1 小时前
大模型(LLM)推理优化技术全景总结
python·算法·大模型
平行侠1 小时前
A10 恶劣环境传感器信号仿真与统计检验台
算法
lly2024061 小时前
建造者模式:构建复杂对象的最佳实践
开发语言
洛水水2 小时前
【力扣100题】34.二叉搜索树中第K小的元素
c++·算法·leetcode
_深海凉_2 小时前
LeetCode热题100-翻转二叉树
算法·leetcode·职场和发展
无尽冬.2 小时前
个人八股之string字符串
java·开发语言·经验分享·后端·异世界