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

一、二叉搜索树 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. 删除三种情况是面试高频考点,必须熟练
相关推荐
秋名RG2 分钟前
Java 基础语法
java·开发语言
java1234_小锋5 分钟前
MyBatis-Plus 3.5.15 已全面支持 Spring Boot 4.0 及 Jackson 3.0
java·spring boot·mybatis
码行山野赴时序归途6 分钟前
C 语言文件操作完全指南:从打开到关闭
c语言·开发语言
张欣-男7 分钟前
3分钟理解线性代数
线性代数·算法
白狐_79811 分钟前
408 数据结构|外部排序优化:怎么减少时间开销
数据结构·算法
小白说大模型11 分钟前
Hermes 全配置指南:从裸版到 AI Agent 天花板
大数据·人工智能·学习·算法·机器学习·数据挖掘
2501_9378609413 分钟前
Java 文件操作与IO(下):字节流、字符流实战IO读写
java·开发语言·python
xixingzhe215 分钟前
spring boot项目接口访问慢问题解决方案
java·数据库·spring boot
MetaLite17 分钟前
SpringBoot整合FastJson2数据脱敏-接口日志与失败降级
java·spring boot·后端
事圆则缓19 分钟前
Kotlin 高阶工程化与 Android 深入实践
android·开发语言·kotlin