0

0

c++中如何实现二叉树后序遍历非递归_c++二叉树后序非递归遍历方法

尼克

尼克

发布时间:2025-09-30 15:52:02

|

632人浏览过

|

来源于php中文网

原创

后序遍历非递归实现的关键是使用单栈配合last指针判断右子树是否已访问,先沿左路入栈,再根据右子树状态决定访问节点或转向右子树,最后更新last指针。

c++中如何实现二叉树后序遍历非递归_c++二叉树后序非递归遍历方法

在C++中实现二叉树的后序遍历非递归方式,关键在于模拟系统的行为,同时确保每个节点在左右子树都访问完毕后再处理自身。与前序和中序不同,后序遍历的非递归实现稍复杂,需要额外判断是否已经访问过子树。

使用单栈实现后序遍历(推荐方法)

核心思路是利用一个栈记录待处理的节点,并用一个指针记录上一次访问的节点,以此判断当前节点的右子树是否已访问。

  • 从根节点开始,将所有“左路”节点入栈(类似中序遍历)
  • 取栈顶节点,但不立即弹出,检查其右子树是否为空或已被访问
  • 若满足条件,则访问该节点并弹出;否则进入右子树继续处理
  • 用 last 指针记录最近访问的节点,避免重复进入右子树

代码实现如下:

```cpp #include #include using namespace std;

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

void postorderTraversal(TreeNode* root) { if (!root) return;

stack stk;
TreeNode* last = nullptr;        // 记录上一个访问的节点
TreeNode* curr = root;

while (curr || !stk.empty()) {
    // 一路向左入栈
    while (curr) {
        stk.push(curr);
        curr = curr->left;
    }

    // 取栈顶,不弹出
    curr = stk.top();

    // 如果右子树为空,或右子树已访问过
    if (!curr->right || curr->right == last) {
        cout << curr->val << " ";
        stk.pop();
        last = curr;           // 更新最后访问节点
        curr = nullptr;        // 避免重复进入左子树
    } else {
        curr = curr->right;    // 进入右子树
    }
}

}

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

DreamGen
DreamGen

一个AI驱动的角色扮演和故事写作的平台

下载

双栈法(易于理解)

另一种方法是使用两个栈:第一个栈按“根→右→左”的顺序压入节点,第二个栈用于反转输出顺序,最终得到“左→右→根”。

  • 先将根入栈1
  • 每次从栈1弹出节点,压入栈2,并依次将左、右孩子压入栈1
  • 最后依次弹出栈2,即为后序结果

代码示例:

```cpp void postorderTwoStacks(TreeNode* root) { if (!root) return; stack stk1, stk2; stk1.push(root); while (!stk1.empty()) { TreeNode* node = stk1.top(); stk1.pop(); stk2.push(node); if (node->left) stk1.push(node->left); if (node->right) stk1.push(node->right); } // 输出栈2 while (!stk2.empty()) { cout << stk2.top()->val << " "; stk2.pop(); } }

注意事项与技巧

单栈法空间效率更高,是面试常见写法。关键点在于 last 指针的使用,它解决了“如何判断右子树已访问”的问题。双栈法逻辑清晰,适合初学者理解后序的本质——逆前序的一种变形。

测试时建议构造如下树验证:
    1
  /   \
 2     3
/
4
正确输出应为:4 2 3 1

基本上就这些,掌握单栈法足以应对大多数场景。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

770

2023.08.22

string转int
string转int

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

381

2023.08.02

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

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

543

2024.08.29

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

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

53

2025.08.29

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

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

197

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

176

2023.11.23

java中void的含义
java中void的含义

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

98

2025.11.27

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

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

394

2023.07.18

c++ 根号
c++ 根号

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

58

2026.01.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.8万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 19万人学习

第二十二期_前端开发
第二十二期_前端开发

共119课时 | 12.5万人学习

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

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