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 的原因)
谢谢

相关推荐
漂流瓶jz1 小时前
UVA-11491 奖品的价值 题解答案代码 算法竞赛入门经典第二版
c++·算法·图论·题解·aoapc·算法竞赛入门经典·uva
weixin_307779135 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
Frank_refuel8 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
hetao173383710 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia62611 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan11 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
2601_9603563812 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah13 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO913 小时前
指针的算术运算详解
java·数据结构·算法
Coder-magician13 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论