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

一、二叉搜索树 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. 删除三种情况是面试高频考点,必须熟练
相关推荐
SL_staff5 分钟前
JVS-APS 实践:用双向反馈闭环打破制造计划孤岛
java·spring cloud·全栈
xys_67821 分钟前
深挖数据结构:树和二叉树(上)
数据结构·算法
\光辉岁月/23 分钟前
3.包装类
java·开发语言·包装类
BeiGuTing_code24 分钟前
Java动态数组(一)
java·数据结构·windows
我命由我1234534 分钟前
软件工程概念 - 可插拔性
java·后端·学习·java-ee·系统架构·软件工程·学习方法
Interview Aid11244 分钟前
Google SWE Intern VO 面经:两轮 Coding,Follow-up 考察 BFS 状态
算法
木易 士心1 小时前
Java 后端驱动远程手机自动化:ADB + Python + 内网穿透实战全解
java·后端·智能手机·自动化
十年Java程序媛1 小时前
JVM 内存区域与对象内存布局|new 对象底层流程,对象头 MarkWord 详解
java·jvm·spring boot
FRing031 小时前
JavaScript入门到精通二十四(正则表达式、元字符、修饰符)
开发语言·前端·javascript·正则表达式
用户094248568031 小时前
第2章:Windows、WSL2 与 Docker 环境搭建Redis
java·jvm