0

0

C++怎么实现二叉树遍历_C++前中后序递归算法【笔记】

冰火之心

冰火之心

发布时间:2026-03-11 14:03:11

|

497人浏览过

|

来源于php中文网

原创

安全递归遍历的关键是:空指针检查必须前置(首行if(root==nullptr)return;),递归调用顺序严格对应遍历定义,深树改用迭代;收集结果宜传vector&引用,避免重复初始化。

c++怎么实现二叉树遍历_c++前中后序递归算法【笔记】

怎么写一个安全的递归遍历函数,不崩栈也不漏节点

直接说结论:C++ 里写前/中/后序遍历,核心不是“怎么递归”,而是「空指针检查必须前置」+「递归调用顺序严格对应遍历定义」。否则轻则结果错乱,重则 Segmentation fault(尤其树深 > 1000 时)。

常见错误现象:nullptr 没判就解引用、递归没写 base case、左右子树访问顺序颠倒(比如中序写成左→右→根)。

  • 所有递归入口第一行必须是 if (root == nullptr) return;,不能靠后续条件“顺便”跳过
  • 参数传 TreeNode* 就够了,别传 TreeNode& —— 空节点无法绑定引用
  • 如果树可能很深(比如 > 2000 层),递归遍历本身就不合适,得换迭代 + std::stack

前序/中序/后序三者只差两行代码,但顺序绝对不能记混

区别全在「访问当前节点」这一步的位置。记混的典型表现:中序输出像前序,或者后序结果为空(实际是访问被跳过了)。

以中序为例,正确结构是:左 → 访问 → 右。如果写成访问 → 左 → 右,那就是前序;写成左 → 右 → 访问,才是后序。顺序错一丁点,输出序列就全错。

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

  • 前序:visit(root); preorder(root->left); preorder(root->right);
  • 中序:inorder(root->left); visit(root); inorder(root->right);
  • 后序:postorder(root->left); postorder(root->right); visit(root);

注意:这里的 visit 是你自己的处理逻辑,比如 std::cout val ,它不参与控制流,只负责输出或存入容器。

蛙蛙写作——超级AI智能写作助手
蛙蛙写作——超级AI智能写作助手

蛙蛙写作辅助AI写文,帮助获取创意灵感,提供拆书、小说转剧本、视频生成等功能,是一款功能全面的AI智能写作工具。

下载

为什么用 std::vector<int></int> 收集结果时总多一个 0 或少一个值

根本原因:返回值传递方式不对,或在递归中重复初始化容器。不是算法错,是 C++ 值语义没处理好。

错误写法:std::vector<int> result; result.push_back(root->val); return result;</int> —— 每次递归都新建 vector,上层结果全丢。

  • 推荐做法:把 std::vector<int>&</int> 当参数传入,所有递归共用同一份内存(避免拷贝,也避免丢失)
  • 不要在递归函数里 return vector,除非你明确写了移动语义(std::move(result)),但没必要复杂化
  • 如果非要用返回值风格,确保顶层调用是 auto res = preorderTraversal(root);,且函数签名是 std::vector<int> preorderTraversal(TreeNode* root)</int>,内部用局部 vector + 递归拼接(性能稍差但逻辑直)

LeetCode 上跑通了,本地 g++ 却报 invalid memory reference

大概率是测试用例里有非法输入:比如 root 是野指针、或某个 TreeNodeleft/right 指向已释放内存。LeetCode 的 judge 环境做了隔离,而本地调试器会严格检查。

排查重点不在遍历逻辑,而在建树过程。比如手写测试用例时用 new TreeNode(1),但忘了初始化 leftright(它们是未定义值,不是 nullptr)。

  • 永远显式初始化指针:TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  • valgrind --tool=memcheck ./a.out 跑本地测试,比看报错信息快得多
  • 如果用智能指针(std::unique_ptr<treenode></treenode>),记得所有 new 都要配对,否则析构时 double free

递归本身很干净,问题往往出在树的构造和边界指针状态上。这点容易被忽略,但占实际调试时间的七成以上。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

846

2023.08.22

string转int
string转int

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

1010

2023.08.02

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

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

610

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

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

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

334

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

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

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

3

2026.03.11

热门下载

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

精品课程

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

共94课时 | 11.1万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.4万人学习

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

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