0

0

c++如何实现二叉树的先序遍历_c++递归与非递归写法【核心】

尼克

尼克

发布时间:2026-02-11 12:31:02

|

638人浏览过

|

来源于php中文网

原创

先序遍历递归最常用因其逻辑最贴近定义(根→左→右),代码直观;但需防栈溢出,须设终止条件、正确访问顺序,并用引用传vector避免拷贝。

c++如何实现二叉树的先序遍历_c++递归与非递归写法【核心】

先序遍历递归写法为什么最常用?

因为逻辑最贴近定义:根 → 左子树 → 右子树,代码几乎就是人话翻译。但要注意栈溢出风险——深度超过系统默认栈限制(通常几千层)就会崩,比如退化成链表的二叉搜索树。

实操建议:

  • 递归函数必须有明确终止条件:if (root == nullptr) return;
  • 访问顺序不能错:先处理root->val,再递归preorderTraversal(root->left),最后preorderTraversal(root->right)
  • 如果需要返回结果而非仅打印,用引用传入vector& res避免频繁拷贝

示例片段:

Interior AI
Interior AI

AI室内设计,上传室内照片自动帮你生成多种风格的室内设计图

下载
void preorder(TreeNode* root, vector& res) {
    if (!root) return;
    res.push_back(root->val);  // 根
    preorder(root->left, res);  // 左
    preorder(root->right, res); // 右
}

非递归先序遍历怎么用栈模拟?

核心是“边访问边压右再压左”——因为栈是后进先出,要让左子树先被弹出,就得先把右子树压进去。

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

常见错误现象:

  • 压栈顺序反了(先压左再压右),导致遍历变成根→右→左
  • 忘记判空就直接访问root->left,触发段错误
  • 循环条件写成!st.empty()却没在循环内弹栈,死循环

实操建议:

  • 初始化栈时只压入root(前提是root != nullptr
  • 每次pop一个节点,立刻访问;若它有右孩子,压右;若有左孩子,压左
  • stack st,别用stack存值——你得靠指针继续往下走

示例片段:

vector preorderTraversal(TreeNode* root) {
    vector res;
    if (!root) return res;
    stack st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* node = st.top(); st.pop();
        res.push_back(node->val);
        if (node->right) st.push(node->right); // 先压右
        if (node->left)  st.push(node->left);  // 后压左
    }
    return res;
}

迭代器风格或统一遍历框架下怎么写?

如果你正在封装一个支持begin()/end()BinaryTree类,或者想和中序/后序共享结构,就得用“访问标记”方式:每个节点入栈两次,第一次带标记false表示待展开,第二次带true表示可访问。

性能影响明显:空间多一倍,且每次都要判断标记位;但好处是三种遍历只需改几行。

关键点:

  • pair代替裸指针
  • 遇到bool == false时,按先序顺序逆序压栈(右→左→根),并把根的标记设为true
  • 遇到bool == true,直接res.push_back

LeetCode 提交时要注意哪些边界?

题干说“二叉树节点数 ≤ 10⁴”,但不代表不会给你nullptr输入。很多本地测试通过的代码在线上挂,就是因为没处理空树。

容易被忽略的地方:

  • TreeNode定义里没有默认构造函数,别写TreeNode()初始化
  • C++11 后推荐用nullptr而非NULL0作为空指针
  • 非递归版本中,stack不支持front(),只能用top();别和queue搞混
  • 递归版若用vector返回,别在每次递归里新建——要么传引用,要么用移动语义return std::move(res)

真正麻烦的不是写法本身,而是当树极深又极偏时,递归爆栈、迭代多耗内存、统一框架多绕两步——选哪种,得看你的场景到底卡在哪。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

243

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

685

2024.03.01

if什么意思
if什么意思

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

804

2023.08.22

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

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

409

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

586

2023.08.10

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

22

2025.11.16

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

59

2026.02.11

Yandex网页版官方入口使用指南_国际版与俄罗斯版访问方法解析
Yandex网页版官方入口使用指南_国际版与俄罗斯版访问方法解析

本专题全面整理了Yandex搜索引擎的官方入口信息,涵盖国际版与俄罗斯版官网访问方式、网页版直达入口及免登录使用说明,帮助用户快速、安全地进入Yandex官网,高效使用其搜索与相关服务。

172

2026.02.11

虫虫漫画网页版入口与免费阅读指南_正版漫画全集在线查看方法
虫虫漫画网页版入口与免费阅读指南_正版漫画全集在线查看方法

本专题系统整理了虫虫漫画官网及网页版最新入口,涵盖免登录观看、正版漫画全集在线阅读方式,并汇总稳定可用的访问渠道,帮助用户快速找到虫虫漫画官方页面,轻松在线阅读各类热门漫画内容。

38

2026.02.11

热门下载

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

精品课程

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

共94课时 | 9.2万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.2万人学习

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

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