c/c++中的二叉树进阶

1. 二叉搜索树

二叉搜索树(Binary Search Tree,简称 BST) 也叫二叉排序树,是最基础的有序树形结构,C++ std::map 的底层雏形(标准库用红黑树 = 平衡版 BST),核心特点:有序、快速查找、插入、删除。

1.核心性质

满足4 条铁律,就是二叉搜索树:

1.左子树的所有节点值 < 根节点值

2.右子树的所有节点值 > 根节点值

3.左、右子树也必须是二叉搜索树

4.中序遍历结果 = 升序有序序列(最核心特性!)

无重复节点值(和 map 的 key 唯一一致)

这就是一颗标准的二叉搜索树:

中序遍历:2 → 3 → 4 → 5 → 6 → 7 → 8(严格升序)

2.、三大核心操作

1. 查找操作

规则:

值 < 根 → 查左子树

值 > 根 → 查右子树

值 = 根 → 找到

到空节点 → 没找到

cpp 复制代码
// 递归查找
Node* search(Node* root, int target) {
    // 空树/没找到
    if (root == nullptr) return nullptr;
    // 找到目标
    if (root->val == target) return root;
    // 目标更小,查左子树
    if (target < root->val) return search(root->left, target);
    // 目标更大,查右子树
    else return search(root->right, target);
}
2.插入操作

规则:查找的过程中,找到空位置直接插入,保证有序。

插入后依然满足 BST 性质

重复值不插入(保持唯一)

cpp 复制代码
// 递归插入
Node* insert(Node* root, int val) {
    // 找到空位置,创建新节点
    if (root == nullptr) return new Node(val);
    
    // 值已存在,不插入
    if (val == root->val) return root;
    
    // 值更小,插入左子树
    if (val < root->val) root->left = insert(root->left, val);
    // 值更大,插入右子树
    else root->right = insert(root->right, val);
    
    return root;
}
3. 删除操作

删除后必须保持 BST 有序,分三种场景:

情况 1:删除叶子节点(无孩子)

直接删除,置空即可。

例:删除 2、4、6、8

情况 2:删除只有一个孩子的节点

用孩子节点替代被删节点。

例:删除只有左 / 右孩子的节点

情况 3:删除有两个孩子的节点(核心)

找后继节点(右子树的最小值) 替代,再删除后继节点。

例:删除根节点 5 → 用 6 替代

cpp 复制代码
// 找右子树的最小值(后继节点)
Node* getMin(Node* node) {
    while (node->left) node = node->left;
    return node;
}

// 递归删除节点
Node* remove(Node* root, int val) {
    if (root == nullptr) return nullptr;

    // 查找要删除的节点
    if (val < root->val) root->left = remove(root->left, val);
    else if (val > root->val) root->right = remove(root->right, val);
    // 找到待删除节点
    else {
        // 情况1:无孩子(叶子节点)
        if (root->left == nullptr && root->right == nullptr) {
            delete root;
            return nullptr;
        }
        // 情况2:只有一个孩子
        else if (root->left == nullptr) {
            Node* temp = root->right;
            delete root;
            return temp;
        }
        else if (root->right == nullptr) {
            Node* temp = root->left;
            delete root;
            return temp;
        }
        // 情况3:两个孩子 → 找右子树最小值替代
        else {
            Node* minNode = getMin(root->right);
            root->val = minNode->val;                // 替换值
            root->right = remove(root->right, minNode->val); // 删除后继节点
        }
    }
    return root;
}

3.时间复杂度

操作 平均情况 最坏情况(退化成链表)
查找 O(log n) O(n)
插入 O(log n) O(n)
删除 O(log n) O(n)

致命缺陷:

如果插入有序数据(1→2→3→4→5),BST 会退化成链表,效率暴跌。

和红黑树的关系:

二叉搜索树:不平衡,最坏 O (n)

红黑树:自平衡二叉搜索树,永远保持 O (log n)

std::map 底层 = 红黑树(不用普通 BST 的原因)
谢谢

相关推荐
Niuguangshuo3 小时前
论文解读:CTC,端到端序列识别的开山之作
算法·语音识别
讳疾忌医丶3 小时前
深度拆解 RocksDB 内核:基于 C++17 的 FIFO 调度状态机与温度阶梯自愈设计
java·c++·算法·架构
2401_868534783 小时前
OpenStack 架构全景:八个核心组件深度拆解
c++·需求分析
高亦真4 小时前
今天是学习嵌入式的第37天
linux·学习·算法
软件课代表CiCi4 小时前
运行库是什么?电脑缺运行库怎么办?c++运行库缺失修复全攻略
开发语言·c++·windows·电脑·dll修复·dll丢失·运行库
蒸蒸yyyyzwd5 小时前
从面经中学到的三件事
c++·笔记
时时三省5 小时前
【时时三省】计算机c语言二级考试选择题重点
c++
罗西的思考5 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 --- (2)--- 训练
人工智能·算法·机器学习
深圳市方中禾科技6 小时前
FZH1625 LCD 驱动芯片深度评测与实战指南
算法·led
我不会起名字3227 小时前
一天一道算法题(34):回溯法的经典例题(子集)
java·数据结构·python·算法·golang·深度优先·力扣