C++实现二叉搜索树BST的节点删除算法 _ 替代节点寻找逻辑详解【源码】

小晨酱_1024

小晨酱_1024

2026-05-05

871人浏览

原创

二叉搜索树删除节点的核心在于正确选择并处理替代节点:无子节点则置空父指针,仅一子节点则直接顶替,两子节点时须用右子树最小值(或左子树最大值)进行节点级替换,并妥善处理其子树。

c++实现二叉搜索树bst的节点删除算法 _ 替代节点寻找逻辑详解【源码】

删除节点时找不到替代节点?先明确三种情况的处理边界

二叉搜索树删除节点的核心难点不在递归或指针操作,而在于「替代节点」的选择逻辑是否覆盖全部情况。实际编码中,deleteNode 函数常在「被删节点有两个子节点」时出错——不是选了右子树最小值,就是误用左子树最大值,更常见的是没处理替代节点自身有子树的情形。

必须区分清楚:
- 被删节点无子节点 → 直接置空父指针
- 被删节点仅有一个子节点 → 用该子节点顶替自身位置
- 被删节点有两个子节点 → 必须从左子树找最大值 或 右子树找最小值(二者等价,但实现细节不同)

  • 选右子树最小值(inorder successor)更常见:它一定没有左子节点,但可能有右子节点,替换后需将其右子树“接回”原位置
  • 选左子树最大值(inorder predecessor)同理:它一定没有右子节点,但可能有左子节点
  • 两种策略不能混用;同一棵 BST 中应固定一种,否则中序遍历结果可能错乱

右子树找最小值时,为什么不能直接 return node->right->val?

这是初学者最常写的错误:return node->right->val 或类似赋值,本质是把值拷贝过去,却忽略了替代节点自身的结构残留。BST 删除要求的是「节点级替换」,而非「值覆盖」——否则原替代节点仍挂在树中,造成内存泄漏和逻辑断裂。

正确做法是:找到右子树最左节点(即最小值节点),将其从原位置摘下,再将它的值赋给待删节点,最后释放该节点内存。但注意:minNode 可能带右子树,摘下后必须让其父节点指向它的右子节点。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
TreeNode* findMin(TreeNode* node) {
    while (node->left) node = node->left;
    return node;
}
<p>TreeNode<em> deleteNode(TreeNode</em> root, int key) {
if (!root) return nullptr;
if (key 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* minNode = findMin(root->right);
root->val = minNode->val; // 仅复制值
root->right = deleteNode(root->right, minNode->val); // 真正删除它
}
return root;
}</p>

替代节点被删后,父节点指针没更新?检查 findMin 的返回方式

findMin 如果只返回节点值或浅拷贝指针,会导致后续 deleteNode(root->right, minNode->val) 在右子树中重新搜索——这不仅低效,还可能因重复值误删其他节点。关键点在于:findMin 必须返回原始树中的节点指针,且调用方要确保该节点能被唯一定位。

常见坑:
- 把 findMin 写成递归并返回局部变量地址
- 在 deleteNode 里对 minNode 做了修改(如重连指针),但没同步更新其父节点的 left 字段
- 忘记 minNode 的父节点可能是 root->right 本身(即右子节点就是最小值),此时要特殊处理 root->right = minNode->right

  • 安全做法:不单独写 findMin,而是在删除逻辑中边找边改父指针
  • 或者用引用参数传入父节点指针,在 findMin 中一并更新
  • 更稳妥的是统一用「用右子节点替代,再递归删右子树最小值」,避免手动维护父指针

C++ 中 delete 后悬空指针与 RAII 的取舍

标准实现里,delete 节点后未置空其左右指针,后续若意外访问会崩溃。但真正在意内存安全的工程代码,往往不手写 delete,而是用智能指针(如 std::unique_ptr<treenode></treenode>)。这时 deleteNode 返回的是移动后的 unique_ptr,天然规避悬空问题。

不过要注意:
- unique_ptr 版本无法直接用 root->left = deleteNode(...),必须写成 root->left = std::move(deleteNode(...))
- 所有节点创建必须用 std::make_unique,否则混合裸指针易出错
- 调试时打印树结构会变麻烦,因为 get() 返回的裸指针生命周期难追踪

裸指针版本简洁,适合教学和竞赛;生产环境建议封装一层 NodeManager 类管理生命周期,而不是在每个 delete 后机械加 node = nullptr。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习