0

0

C++怎么实现二叉搜索树_C++树形结构增删改查【详解】

尼克

尼克

发布时间:2026-03-12 19:34:03

|

231人浏览过

|

来源于php中文网

原创

insert函数必须返回当前子树根节点,遇nullptr新建节点并返回;递归调用后需显式赋值(如root->left = insert(root->left, val));重复值直接丢弃。

c++怎么实现二叉搜索树_c++树形结构增删改查【详解】

怎么写一个能用的 insert 函数(不崩、不重复、不漏节点)

二叉搜索树的插入不是简单比大小就递归完事。常见错误是没处理空指针、忘了返回新节点导致链断开,或者没检查重复值导致逻辑错乱。

核心原则:每次递归必须返回当前子树根节点,让父节点能正确接住;重复值直接丢弃(BST 通常不允许重复)。

  • insert 函数签名建议用 TreeNode* insert(TreeNode* root, int val),别用引用传参——C++ 里容易误以为改了 root 就等于改了上层指针
  • 遇到 nullptr 就新建节点并返回,这是唯一创建节点的地方
  • 递归调用后必须显式赋值:比如 root->left = insert(root->left, val),否则修改不会反映到树结构上
  • 如果要求支持重复值(如计数 BST),得额外加字段,不能只靠 val 比较

查不到节点时 find 返回什么最安全

返回 nullptr 是标准做法,但容易在后续解引用时报 segmentation fault。真正的问题不在返回值,而在调用方有没有检查。

典型翻车场景:直接写 if (find(root, 5)->val == 5),一旦没找到,nullptr->val 立刻崩溃。

立即学习C++免费学习笔记(深入)”;

  • 永远先判空再访问成员:TreeNode* node = find(root, 5); if (node) { ... }
  • 不要把 find 当布尔函数用,它返回的是指针,语义是“给你节点地址”,不是“是否存在”
  • 如果只是判断存在性,单独写个 exists 函数更清晰,内部复用 find 即可

删除节点为什么比插入难得多

删叶子节点和删单子节点还好办;真正卡住人的是删有两个子节点的节点——你得找中序后继(右子树最小值)或前驱(左子树最大值)来顶替,还要保证替换后仍是 BST。

腾讯交互翻译
腾讯交互翻译

腾讯AI Lab发布的一款AI辅助翻译产品

下载

常见坑是:找到后继后,只复制了值,没真正删掉后继节点,导致数据残留;或者删后继时没更新父节点指针,树结构断裂。

  • 删双子节点时,推荐统一用右子树最小值(即 minNode(root->right))替代,逻辑更对称
  • 替换完值后,必须递归删除那个最小节点——注意这次删除一定落在右子树的最左端,所以最多只有一个子节点,不会再次触发双子分支
  • 别在删除函数里 new 新节点,也不该修改被删节点的左右指针以外的内容

std::unique_ptr<treenode></treenode> 能省心吗

能自动管理内存,但会改变所有接口签名和递归逻辑,初学者反而更容易写错。比如 insert 得改成 std::unique_ptr<treenode> insert(std::unique_ptr<treenode>&& root, int val)</treenode></treenode>,移动语义一搞混,节点就提前释放了。

真实项目里值得上智能指针,但练手或面试实现 BST 时,裸指针 + 明确的 delete 更可控。

  • 如果坚持用 unique_ptr,所有递归调用都得用 std::move 传递所有权,比如 root->left = insert(std::move(root->left), val)
  • find 这种只读操作,参数应该用 const std::unique_ptr<treenode>&</treenode>,避免意外转移
  • 调试时打印地址会看到 get() 返回的裸指针,别把它当普通指针去 delete

BST 的难点从来不在算法思想,而在于指针操作的每一步是否真的改变了树的拓扑连接。少一次赋值、多一次 new、漏一个空检查,整棵树就 quietly 不工作了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

562

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1030

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

612

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1925

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

656

2025.10.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.2万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号