C++ 怎么实现二叉搜索树 C++ BST插入查找删除代码【数据结构】

发布时间 - 2026-02-01 00:00:00    点击率:
BST节点必须用指针(非值语义),构造函数显式初始化left/right为nullptr;insert需返回新节点并由上层赋值;delete双子节点时须用中序后继替换并递归删除;find推荐返回TreeNode*以支持后续修改。

怎么写一个能用的 BST 节点结构

C++ 实现 BST 的起点不是算法,而是节点定义是否支持后续操作。常见错误是只存 val、不存 leftright 指针,或者用裸指针但没初始化为 nullptr,导致未定义行为。

  • 必须用指针(TreeNode* 或智能指针),不能用值语义嵌套对象(会无限递归构造)
  • 构造函数里把 leftright 显式设为 nullptr,避免野指针
  • 如果用 std::unique_ptr,注意移动语义和 release() 的使用时机

示例最小可用节点:

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

insert 递归实现为什么总崩在空节点插入

崩的原因几乎都是:递归到底层时传入的是局部指针副本,修改它不会影响上层的 root 或子节点指针。比如写成 node = new TreeNode(val),只是改了形参,父节点的 leftright 仍是 nullptr

正确做法只有两种:

  • 传指针的引用:void insert(TreeNode*& node, int val)
  • 返回新节点地址,由上层赋值:node->left = insert(node->left, val)

推荐后者,逻辑更清晰、无副作用。示例关键片段:

TreeNode* insert(TreeNode* root, int val) {
    if (!root) return new TreeNode(val);
    if (val < root->val)
        root->left = insert(root

->left, val); else root->right = insert(root->right, val); return root; }

delete 节点时怎么处理有两个子节点的情况

这是 BST 删除最易错的部分。很多人直接删掉目标节点、把左右子树“拼”起来,结果破坏 BST 性质。正确方式是找中序后继(右子树最左节点)或中序前驱(左子树最右节点)来替换。

  • 选中序后继更常见:它一定没有左孩子,删它只需处理单子节点或叶子情况
  • 替换时不是交换值(虽然可行),而是用后继节点“顶替”被删节点位置,再删后继节点
  • 注意:后继节点可能位于右子树深层,删除它时仍要递归调用 deleteNode,不能手动 delete

关键逻辑节选:

TreeNode* deleteNode(TreeNode* root, int key) {
    if (!root) return nullptr;
    if (key < root->val)
        root->left = deleteNode(root->left, key);
    else if (key > root->val)
        root->right = deleteNode(root->right, key);
    else {
        if (!root->left) return root->right;
        if (!root->right) return root->left;
        // 找右子树最左节点(中序后继)
        TreeNode* successor = root->right;
        while (successor->left) successor = successor->left;
        root->val = successor->val;
        root->right = deleteNode(root->right, successor->val); // 递归删后继
    }
    return root;
}

find 查找函数要不要返回指针还是布尔值

取决于使用场景。如果只是判断存在性,返回 bool 最轻量;但如果后续要修改该节点(比如计数、打标记),必须返回 TreeNode*,否则得再查一遍。

  • 返回 TreeNode* 更通用,且与 insert/delete 接口风格一致
  • 注意:返回 nullptr 表示未找到,别和有效节点混淆;调用方必须判空
  • 不要用 static 局部变量或全局缓存来“优化”查找——BST 本身不保证平衡,缓存失效成本高,反而增加复杂度

示例简洁版:

TreeNode* find(TreeNode* root, int key) {
    if (!root || root->val == key) return root;
    return key < root->val ? find(root->left, key) : find(root->right, key);
}

BST 的难点不在代码行数,而在指针所有权和递归边界。哪怕只漏了一个 return root,或某次 delete 后没置空指针,运行时崩溃就很难定位。写完务必用三类 case 测:空树、单节点、左右子树都非空的根节点删除。


# node  # c++  # 为什么  # Static  # 构造函数  # 局部变量  # 递归  # bool  # int  # void  # 指针  # 数据结构  # 接口  # 形参  # 空指针  # delete  # 对象  # 算法  # 子树  # 的是  # 都是  # 这是  # 很难  # 两种  # 很多人  # 只需  # 设为 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 制作公司内部网站有哪些,内网如何建网站?  如何在阿里云域名上完成建站全流程?  lovemo网页版地址 lovemo官网手机登录  Laravel如何创建自定义中间件?(Middleware代码示例)  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案  Laravel如何实现数据库事务?(DB Facade示例)  Android Socket接口实现即时通讯实例代码  如何在 React 中条件性地遍历数组并渲染元素  制作电商网页,电商供应链怎么做?  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  ,怎么在广州志愿者网站注册?  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  Laravel如何使用Telescope进行调试?(安装和使用教程)  Laravel路由怎么定义_Laravel核心路由系统完全入门指南  Python正则表达式进阶教程_复杂匹配与分组替换解析  如何用虚拟主机快速搭建网站?详细步骤解析  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  如何在Windows服务器上快速搭建网站?  如何在IIS服务器上快速部署高效网站?  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法  手机网站制作与建设方案,手机网站如何建设?  php 三元运算符实例详细介绍  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  如何用AI帮你把自己的生活经历写成一个有趣的故事?  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  在centOS 7安装mysql 5.7的详细教程  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  如何在景安服务器上快速搭建个人网站?  Python图片处理进阶教程_Pillow滤镜与图像增强  如何用IIS7快速搭建并优化网站站点?  如何用狗爹虚拟主机快速搭建网站?  如何为不同团队 ID 动态生成多个独立按钮  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  香港网站服务器数量如何影响SEO优化效果?  如何在IIS7中新建站点?详细步骤解析  千库网官网入口推荐 千库网设计创意平台入口  网易LOFTER官网链接 老福特网页版登录地址  如何快速搭建FTP站点实现文件共享?  JavaScript如何实现音频处理_Web Audio API如何工作?  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权