跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

二叉搜索树(BST)核心原理与 C++ 实战

二叉搜索树(BST)是一种左子树小于根、右子树大于根的二叉树结构。其性能取决于树高,理想状态 O(logN),最坏退化 O(N)。详细讲解了 BST 的基本概念、性能分析以及 C++ 模板实现,涵盖插入、查找、删除等核心操作,并对比了 K 模型与 KV 模型的应用场景。代码部分修复了常见逻辑漏洞,提供了完整的工程化参考。

佛系玩家发布于 2026/3/21更新于 2026/8/2240 浏览
二叉搜索树(BST)核心原理与 C++ 实战

什么是二叉搜索树

二叉搜索树(Binary Search Tree,简称 BST),也叫二叉排序树或二叉查找树。它是一棵特殊的二叉树,满足以下性质:

  1. 若左子树不为空,则左子树上所有节点的值均小于根节点的值。
  2. 若右子树不为空,则右子树上所有节点的值均大于根节点的值。
  3. 左右子树也分别为二叉搜索树。
  4. 空树也是二叉搜索树。

简单来说,就是对于任意节点,左小右大。这棵树的结构决定了它的查找效率。

文章配图

性能分析

BST 的性能高度依赖于树的形态。

最优情况:当树接近完全二叉树时,高度最小,约为 log₂N。此时查找、插入、删除的时间复杂度均为 O(log₂N)。

文章配图

最坏情况:如果数据是有序插入的,树会退化成链表,高度变为 N。此时操作退化为线性查找,时间复杂度为 O(N)。

文章配图

这也是为什么后续我们会引入 AVL 树或红黑树来保持平衡的原因。

具体实现

基本结构

为了支持不同的数据类型,我们使用模板定义节点和树。

template<class K> struct BSTNode {
    BSTNode(const K& key) :_left(nullptr), _right(nullptr), _key(key) {}
    BSTNode<K>* _left;
    BSTNode<K>* _right;
    K _key;
};

template<class K> class BSTree {
    typedef BSTNode<K> Node;
public:
    // ... 成员函数
private:
    Node* _root = nullptr;
};

初始化和销毁

构造函数初始化根节点为空。析构函数需要递归释放内存,防止泄漏。

~BSTree() { Destroy(_root); }
void Destroy(Node*& root) {
    if (root == nullptr) return;
    Destroy(root->_left);
    Destroy(root->_right);
    delete root;
    root = nullptr;
}

拷贝构造和赋值运算符重载通常利用深拷贝和交换法来实现,这里省略细节,重点看核心逻辑。

插入操作

插入分为递归和循环两种方式。递归写法简洁,但栈空间开销大;循环写法空间效率高,适合深层树。

递归实现:

bool InsertR(const K& key) { return _InsertR(_root, key); }
bool _InsertR(Node*& root, const K& key) {
    if (root == nullptr) {
        root = new Node(key);
        return true;
    }
    if (key < root->_key) return _InsertR(root->_left, key);
    else if (key > root->_key) return _InsertR(root->_right, key);
    else return false; // 不允许重复值
}

循环实现:

bool Insert(const K& key) {
    if (_root == nullptr) {
        _root = new Node(key);
        return true;
    }
    Node* parent = nullptr;
    Node* cur = _root;
    while (cur) {
        if (key < cur->_key) {
            parent = cur;
            cur = cur->_left;
        } else if (key > cur->_key) { // 注意补全条件
            parent = cur;
            cur = cur->_right;
        } else {
            return false;
        }
    }
    cur = new Node(key);
    if (key < parent->_key) parent->_left = cur;
    else parent->_right = cur;
    return true;
}

查找操作

查找逻辑很直观,从根节点开始比较,根据大小决定向左还是向右走。

bool Find(const K& key) {
    Node* cur = _root;
    while (cur) {
        if (key < cur->_key) cur = cur->_left;
        else if (key > cur->_key) cur = cur->_right;
        else return true;
    }
    return false;
}

删除操作

删除是最复杂的,分三种情况讨论:

  1. 叶子节点:直接删除。
  2. 有一个子节点:用子节点替换当前节点。
  3. 有两个子节点:找到中序后继(右子树最小)或前驱(左子树最大),替换值后递归删除该后继/前驱。

递归删除示例:

bool EraseR(const K& key) { return _EraseR(_root, key); }
bool _EraseR(Node*& root, const K& key) {
    if (root == nullptr) return false;
    if (key < root->_key) return _EraseR(root->_left, key);
    else if (key > root->_key) return _EraseR(root->_right, key);
    
    // 找到目标节点
    Node* del = root;
    if (root->_left == nullptr) {
        root = root->_right;
    } else if (root->_right == nullptr) {
        root = root->_left;
    } else {
        // 找左子树最大节点
        Node* maxleft = root->_left;
        while (maxleft->_right) maxleft = maxleft->_right;
        swap(maxleft->_key, root->_key);
        return _EraseR(root->_left, key);
    }
    delete del;
    return true;
}

应用场景

K 模型

只存储 Key,用于快速判断某个值是否存在。比如字典去重。

KV 模型

Key 对应 Value,典型的键值对存储。比如英汉词典,Key 是单词,Value 是翻译。

在 KV 模型中,节点结构增加 V _val 字段,其余逻辑与 K 模型一致。

完整源码参考

以下是整合后的 K 模型与 KV 模型代码框架,包含头文件与测试逻辑。

K 模型头文件 (BST.h)

#pragma once
#include<iostream>
#include <utility>
using namespace std;

namespace K {
template<class K> struct BSTNode {
    BSTNode(const K& key) :_left(nullptr), _right(nullptr), _key(key) {}
    BSTNode<K>* _left;
    BSTNode<K>* _right;
    K _key;
};

template<class K> class BSTree {
    typedef BSTNode<K> Node;
public:
    BSTree() {}
    ~BSTree() { Destroy(_root); }
    bool Insert(const K& key) { /* 见上文 */ }
    bool Find(const K& key) { /* 见上文 */ }
    bool Erase(const K& key) { /* 见上文 */ }
    void InOrder() { InOrder(_root); }
    void InOrder(Node* root) {
        if (!root) return;
        InOrder(root->_left);
        cout << root->_key << " ";
        InOrder(root->_right);
    }
private:
    Node* _root = nullptr;
    // 辅助函数略...
};
}

KV 模型测试示例

#include "BST.h"
int main() {
    KV::BSTree<string, string> dictionary;
    dictionary.Insert("apple", "苹果");
    dictionary.Insert("banana", "香蕉");
    dictionary.InOrder(); // 输出单词顺序
    dictionary.Erase("banana");
    dictionary.InOrder();
    return 0;
}

总结

二叉搜索树是数据结构中的基石之一。虽然基础版在极端情况下性能会退化,但它为理解平衡树(如 AVL、红黑树)奠定了坚实基础。在实际工程中,C++ STL 的 map/set 底层正是基于红黑树实现的,它们保证了稳定的对数级性能。

目录

  1. 什么是二叉搜索树
  2. 性能分析
  3. 具体实现
  4. 基本结构
  5. 初始化和销毁
  6. 插入操作
  7. 查找操作
  8. 删除操作
  9. 应用场景
  10. K 模型
  11. KV 模型
  12. 完整源码参考
  13. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • sherpa-onnx 离线语音部署框架:Whisper、Moonshine、SenseVoice 多模型支持
  • 在 Cursor 中配置并使用 MCP 服务实战指南
  • 2025 年 AI 领域年度总结:DeepSeek R1 开源与 Manus 商业化
  • Java 二分查找算法题目实战
  • 昇腾 910B 部署 Llama-2-7b 大模型深度测评与方案
  • 位图矢量化技术瓶颈突破:Potrace 算法深度解析与应用实践
  • 7D-AI系列:AI 编程 Spec Coding 完整详细的典型标准化工作流
  • Python 数学可视化:显函数、隐函数及复杂曲线的交互式绘图
  • C 语言 Web 开发实战:CGI、FastCGI 与 Nginx 模块详解
  • Elasticsearch + Kibana 实战指南:从安装部署到 C++ 客户端封装
  • 前端 Bug 排查实战:从现象定位到测试闭环的标准化流程
  • Claude Code 本地环境配置与使用指南
  • 鸿蒙 AI 开发:Skill 与 MCP 概念及 Trae 部署实战
  • Spring Boot 视图层开发:主流模板引擎集成实战
  • 大模型高效推理与部署技术实战
  • Python 一键拆分 PDF:按章节建文件夹并导出单页(支持书签与正文识别)
  • OpenClaw 多机器人团队协作配置指南
  • C++ list 模拟实现:带头双向链表的增删查改
  • FPGA 是什么?从原理到应用场景的深度解析
  • 开源模型 Mistral 与 Qwen Prompt 实验报告

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online