Leetcode145 二叉树的后序遍历

二叉树后续非递归遍历(很多人的盲区?) 大家好,我是Johngo! 今天有在校的粉丝想要C语言实现的树的后续遍历的详细讲解,今天就来看看。 后面给到了所有的代码,可以直接运行! 二叉树后序遍历 二叉树的遍历方式主要由先序遍历、中序遍历和后续遍历,还后就是层次遍历 感受完前两篇的遍历方式,本节来看看后序遍历 后序遍历过程 a. 先序遍历其左子树; b. 先序遍历其右子树; c. 访问根节点; 然后就是一直递归下去,在访问到节点的时候,可以进行节点的相关处理,比如说简单的访问节点值 下图是一棵二叉树,我们来手动模拟一下后序遍历过程 按照上述后序遍历 阅读详情

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

知识点:栈

栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底。元素入栈指的是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

思路:

既然二叉树的前序遍历和中序遍历都可以使用栈来代替递归,那后序遍历是否也可以呢?答案是可以的,但是会比前二者复杂一点点。

根据后序遍历“左右根”的顺序,那么后序遍历也与中序遍历类似,要先找到每棵子树的最左端节点:

1

2

3

4

5

//每次找到最左节点

while(root != NULL){

    s.push(root);

    root = root->left;

}

然后我们就要访问该节点了嘛?不不不,如果它还有一个右节点呢?根据“左右根”的原则,我还要先访问右子树。我们只能说它是最左端的节点,它左边为空,但是右边不一定,因此这个节点必须被看成是这棵最小的子树的根。要怎么访问根节点呢?

我们都知道从栈中弹出根节点,一定是左节点已经被访问过了,因为左节点是子问题,访问完了才回到父问题,那么我们还必须要确保右边也已经被访问过了。如果右边为空,那肯定不用去了,如果右边不为空,那我们肯定优先进入右边,此时再将根节点加入栈中,等待右边的子树结束。

1

2

3

4

//该节点再次入栈

s.push(node);

//先访问右边

root = node->right;

不过,当右边被访问了,又回到了根,我们的根怎么知道右边被访问了呢?用一个前序指针pre标记一下,每个根节点只对它的右节点需要标记,而每个右节点自己本身就是一个根节点,因此每次访问根节点的时候,我们可以用pre标记为该节点,回到上一个根节点时,检查一下,如果pre确实是它的右子节点,哦那正好,刚刚已经访问过了,我现在可以安心访问这个根了。

1

2

3

4

5

6

7

//如果该元素的右边没有或是已经访问过

if(node->right == NULL || node->right == pre){

    //访问中间的节点

    res.push_back(node->val);

    //且记录为访问过了

    pre = node;

}

具体做法:

  • step 1:开辟一个辅助栈,用于记录要访问的子节点,开辟一个前序指针pre。
  • step 2:从根节点开始,每次优先进入每棵的子树的最左边一个节点,我们将其不断加入栈中,用来保存父问题。
  • step 3:弹出一个栈元素,看成该子树的根,判断这个根的右边有没有节点或是有没有被访问过,如果没有右节点或是被访问过了,可以访问这个根,并将前序节点标记为这个根。
  • step 4:如果没有被访问,那这个根必须入栈,进入右子树继续访问,只有右子树结束了回到这里才能继续访问根。

图解:

代码实现:

 List<Integer> res = new ArrayList<>();
        if(root == null)
            return res;
        Stack<TreeNode> s = new Stack<>();
        TreeNode pre = null;//已经访问过的节点,用于判断增加根节点时使用
        while(root != null || !s.isEmpty()){
            while(root != null){
                s.push(root);
                root = root.left;
            }
            TreeNode cur = s.pop();
            //如果该元素的右边没有或是已经访问过
            if(cur.right == null || cur.right == pre){
                //访问中间的节点
                res.add(cur.val);
                pre = cur;
            }
            else{
                s.push(cur);//该节点入栈
                root = cur.right;//先访问右节点
            }
        }
        return res;

}

二叉树的前序、中序、后序、层序遍历,递归和迭代两大类解题思路,每类细分不同解法【完整版】附PDF文档 一、二叉树的前序遍历 二叉树的前序遍历的记忆法则是“根左右",即先遍历根节点,再遍历左子树节点,再遍历右子树节点。 以上图为例,前序遍历的结果是【A, B, D, E, C, F, G】 1.1 解题思路:递归 递归是我们实现前中后序遍历最常用的方法。 什么问题可以采用递归求解呢? 需要满足三个条件: 一个问题的解可以分解为若干个子问题的解; 这个问题与分解的子问题,除了数据规模不同外,求解思路相同 存在递归终止条件。 那么在知道一个问题可以采用递归实现之后,如何写出递归代码呢? 关键在于能写出递归 阅读详情

相关推荐

C语言经典算法之二叉树的后序遍历(非递归实现)

在C语言中,二叉树的后序遍历(LRD顺序:左子树-右子树-根节点)非递归实现通常依赖于栈来模拟递归过程。

weixin_56154577的博客 1970

二叉树:后序遍历非递归算法

分析:后序遍历是三种遍历中最难的一种,后序遍历的特点为左右根,并且也需要借助一个栈来完成,如图,虚线表示p,q最开始的位置,用r指向最近访问过的结点。首先从根节点开始,沿着根的左孩子,将左孩子依次进行入栈。当D入栈之后,由于D没有右孩子,所以将D出栈,此时r指向D。 D出栈之后读栈顶元素B,p指向B,发现B有右孩子,然后将右孩子E入栈。 然后判断栈顶元素E,E没有右孩子了,所以将E出栈,此时r指向E。 然后判断栈顶元素B,B的两个孩子都已经操作过了,所以B出栈,p指向A,判断栈顶元素A,A有右孩子,右孩

花间半盘棋 2万+

【简单】力扣算法题解析LeetCode145:二叉树的后序遍历

这篇文章介绍了二叉树后序遍历的迭代实现方法。通过使用显式栈替代递归,结合状态标记(lastVisited指针)来判断右子树是否已处理,实现了高效的后序遍历算法。该算法时间复杂度为O(n),空间复杂度为O(h),其中h为树高。文章包含详细的设计思路、Java代码实现以及边界条件处理,并附有执行效果截图。该方法避免了递归的系统栈开销,通过精确控制节点访问顺序,确保了遍历的正确性和高效性。

ylumwd的博客 1086

二叉树遍历之后序遍历(非递归、递归)入门详解

二叉树后序遍历不如先序遍历简单,是相对最复杂的一种遍历方法。访问结点的次序是:“左—>右—>根”,也就是首先访问左子树,之后访问右子树,最后访问树根。对于左、右子树而言,其访问的次序依然是“左—>右—>根”。也就是说,对于每一棵子树,都是最后访问树根。...

sunnyoldboy博客 3万+

Leetcode——145,二叉树后序遍历

/** * \* Created: liuhuichao * \* Date: 2019/8/21 * \* Time: 28:08 PM * \* Description: 二叉树的后序遍历 : 后序遍历是先遍历左子树,然后遍历右子树,最后访问树的根节点 * \ * 给定一个二叉树,返回它的 后序 遍历。 * <p> * 示例: * <p> ...

我们的征途是星辰大海 735

Harness设计——Anthropic实战:规划器、生成器、评估器三角色协作详解

本文探讨了如何通过多智能体架构突破AI编码的瓶颈问题。文章首先分析了当前AI编码面临的两大核心挑战:上下文窗口限制导致的连贯性丧失,以及自我评估机制缺失引发的质量判断偏差。针对这些问题,作者提出了基于生成对抗网络(GAN)灵感的解决方案,设计了三智能体系统:规划器负责需求分析,生成器执行编码任务,评估器进行质量审查。 实验表明,在前端设计任务中,通过制定可量化的评分标准(设计质量、原创性、工艺、功能性)并建立生成-评估反馈循环,能显著提升输出质量。这种架构随后被扩展到全栈开发领域,采用类似敏捷开发的&quo

oe1019的专栏 865

LeetCode第145题_二叉树的后序遍历

给你一棵二叉树的根节点root,返回其节点值的。

qq_40263592的博客 1391

Apple CarPlay Certification Guide December 2022 解析V1.0

Apple CarPlay Certification Guide December 2022更新说明

m0_74450450的博客 703

LeetCode 145 二叉树的后序遍历 Java

LeetCode 145 二叉树的后序遍历 Java题目描述代码 题目描述 给定一个二叉树,返回它的 后序 遍历。 代码 迭代实现 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * ...

qq_29061435的博客 222

NTFS分区变成RAW别乱修!正确数据恢复与修复方法详解

文件系统是操作系统管理存储数据的核心机制,NTFS作为Windows主流文件系统,一旦分区识别异常,常会显示为RAW格式。分区变RAW通常意味着文件系统入口信息损坏,而非数据物理消失,但若采用错误的修复方式,如直接对RAW分区执行chkdsk /f,可能因系统无法正确识别文件系统结构,导致写入操作落在错误偏移位置,二次破坏本可恢复的数据。正确的处理思路是:先停止一切写入操作,通过扇区级镜像备份保留原始现场,再分析DBR、分区表及$MFT状态,依据诊断结果选择修复或深度扫描恢复。实际排查中,常见问题如DBR记

weixin_31155097的博客 132

国科大人工智能原理与算法-2024-第一次作业-雷震老师

1. 反射行动(比如从热炉子上缩回你的手)是理性的吗?它们是智能的吗? 2. 以下的计算机系统在何种程度上是人工智能的实例: - 超市条码扫描器 - 网络搜索引擎 - 语音激活的电话菜单 - 对网络状态动态响应的网络路由算法 3. 为什么进化会倾向于导致行为合理的系统?设计这样的系统想达到的目标是什么?

MatsumotoChrikk 2926

LeetCode 145二叉树的后序遍历

LeetCode 145二叉树的后序遍历 题目简述:给定一个二叉树,返回它的 后序 遍历。 输入:[1,null,2,3] 输出:[3,2,1] 思路:递归 class Solution { public: vector<int> res; void dfs(TreeNode *root) { if(!root) return; dfs(root->left); dfs(root->right);

XBlog 388

提示libfakeroot.so或libfakeroot-sysv.so出错处理方法

嵌入式Linux、Buildroot交叉编译出现fakeroot问题处理方法。

阿xin*的嵌入式AI 1443

LeetCode 145 二叉树的后序遍历

LeetCode 145 二叉树的后序遍历 题目链接 给定一个二叉树,返回它的 后序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 看题目的意思是想让我们写个非递归的后序遍历,但那个非常复杂,所以我强行来了一波递归????,AC代码如下: /** * Definition for a binary tree node. * struct TreeNode { * int val; * Tr

旺崽的博客 2728

2026年OPPO嵌入式岗位面试题带详细答案

本文总结了OPPO嵌入式岗位面试的核心考点,涵盖硬件驱动、系统启动、Linux内核开发等7大模块共34道典型题目。重点解析了SPI通信协议、中断处理、U-Boot启动流程、Linux驱动开发等关键技术,突出硬件调试与工程实践能力考核。题目设置贴合实际岗位需求,适合校招与社招驱动开发岗位应聘者系统复习,帮助掌握嵌入式开发的核心知识与面试要点。

Open 489

Python爬虫实战:模拟登录知乎 – 通过加密参数和验证码实现自动登录

通过本篇博客的讲解,我们学习了如何通过 POST请求 和 验证码识别,模拟登录知乎并爬取用户信息、问题数据。随着爬虫技术的发展,面对更复杂的反爬虫机制,我们可以不断调整策略,以绕过这些防护,实现数据的自动化抓取。

2201_76125261的博客 731

力扣[LeetCode].145. 二叉树的后序遍历

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} *.

C/C++/Linux/MySQL 445

AUTOSAR进阶图解==>AUTOSAR_EXP_VFB

AUTOSAR虚拟功能总线(VFB)摘要 AUTOSAR虚拟功能总线(VFB)是汽车开放系统架构中的核心抽象概念,为分布式电子系统提供统一通信模型。VFB允许软件组件在不了解底层物理通信机制的情况下交互,通过运行时环境(RTE)实现组件间的数据交换。系统配置过程将抽象的VFB视图转换为具体实现,包括组件到ECU的映射和通信机制选择。VFB采用"last-is-best"语义进行数据通信,并支持模式管理机制,使组件能根据系统状态调整行为。此外,VFB还支持与非AUTOSAR系统的交互,通常

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 1115

LeetCode —— 145. 二叉树的后序遍历

145. 二叉树的后序遍历:递归 + 非递归

微笑,来自内心坚不可摧的自信。 984

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Leetcode145 二叉树的后序遍历 C++,Java,Python

Leetcode145 二叉树的后序遍历 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 博主Github:https://github.com/GDUT-Rp/LeetCode 题目: 给定一个二叉树,返回它的后序 遍历。 示例 1: 输入: [1,null,2,3] ...

Rp的博客 331

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LeetCode145-二叉树的后序遍历

LeetCode145-二叉树的后序遍历 最近全国疫情严重,待在家里没事干,马上又要准备春招了,最近刷刷题,记录一下!再说一句,武汉加油,大家出门记得戴口罩! 1、题目 给定一个二叉树,返回它的后序遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2、思路 ...

sk18192449347的博客 217

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LeetCode145. 二叉树的后序遍历

LeetCode145. 二叉树的后序遍历 非递归: class Solution { public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> result = new LinkedList<>(); Stack<TreeNode> stack = new Stack<>(); if (root

Loser_you的博客 128

LeetCode 145:二叉树的后序遍历(java)

LeetCode 145:二叉树的后序遍历(java) 题目: 解答: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val...

樊凯的博客 597

leetcode-145 | 二叉树的后序遍历

title: leetcode-145 | 二叉树的后序遍历 date: 2019-7-28 15:13:38 comments: true categories: “leetcode” tags: - leetcode 困难难度 - 栈 - 二叉树的遍历 题目描述 给定一个二叉树,返回它的 后序 遍历。 示例: 输入: [1,null,2,3] 1   \  &n...

梦否 482

C/C++描述 LeetCode 145. 二叉树的后序遍历

C/C++描述 LeetCode 145. 二叉树的后序遍历   大家好,我叫亓官劼(qí guān jié ),在优快云中记录学习的点滴历程,时光荏苒,未来可期,加油~博主目前仅在优快云中写博客,唯一博客更新的地址为:亓官劼的博客 本文原创为亓官劼,请大家支持原创,部分平台一直在恶意盗取博主的文章!!! 给定一个二叉树,返回它的 后序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 题解 递归解法:

一起加油 1518

145.力扣LeetCode_二叉树的后序遍历

本文介绍了二叉树后序遍历的递归和非递归实现方法。递归方法采用"左-右-根"的顺序,通过递归调用实现;非递归方法提供了两种实现思路:1) 使用栈和pre指针标记已访问节点,通过判断右子树是否处理来控制访问顺序;2) 使用栈和flag标记法,用0和1标记节点状态,分别表示待处理子树和可访问节点。两种非递归方法都通过栈模拟递归过程,其中pre指针法更简洁,而flag标记法更直观。文章包含详细注释的代码实现,解释了核心思路和关键步骤,适合理解二叉树后序遍历的实现原理。

2401_82472941的博客 635
上一篇: 面试必刷TOP101【二分查找/排序篇】
下一篇: Leetcode104 二叉树的最大深度
魑魅魍魉114
博客等级 码龄10年 165粉丝 240原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值