Leetcode 145. 二叉树的后序遍历

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

题目

给定一个二叉树,返回它的 后序 遍历。

在这里插入图片描述
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

解法一:递归

递归解法不用多说,很简单。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        postorderTraversal(root, res);
        return res;
    }
    
    private void postorderTraversal(TreeNode node, List<Integer> res) {
        if(node == null) return;        
        
        postorderTraversal(node.left, res);
        postorderTraversal(node.right, res);
        res.add(node.val);
    }
}
结果

在这里插入图片描述

解法二:前序遍历逆序

我们观察到:

  • 后序遍历的顺序是:左 -> 右 -> 根,倒着的顺序就是 根 -> 右 -> 左。

  • 前序遍历的顺序是:根 -> 左 -> 右,因此我们只需要简单的更改左右子树的压栈顺序即可。

最后将遍历的结果逆序或者采用头插法,就是后序遍历的结果了。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null) return new ArrayList<>();
        
        LinkedList<Integer> res = new LinkedList<>();
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode node = stack.pop();
            res.addFirst(node.val);
            
            if(node.left != null) {
                stack.push(node.left);
            }
            
            if(node.right != null) {
                stack.push(node.right);
            }
        }
        
        return res;
    }
}
结果

在这里插入图片描述

解法三:完全非递归后序

pre 变量:记录前一个被访问的结点。

具体流程如下:

  1. 先把左结点全部压栈。
  2. 然后观察栈顶结点的右子树是否为 null 或者已经遍历过了。
  3. 如果是 null 或者右子树已经遍历过了,就把当前结点出栈。
  4. 否则当前栈顶结点不出栈,而是去遍历右子树。
代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null) return new ArrayList<>();
        
        LinkedList<Integer> res = new LinkedList<>();
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode cur = root;
        TreeNode pre = null;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            
            TreeNode node = stack.peek();
            if(node.right == null || node.right == pre) {
                stack.pop();
                res.add(node.val);
                pre = node;
                cur = null;                
            } else {
                cur = node.right;
            }
        }
        
        return res;
    }
}
结果

在这里插入图片描述

解法四:前中后序非递归通用解

对于二叉树中的任何一个节点而言,它都有两种角色:

  1. flag = true:作为值,此时可加入结果集。
  2. flag = false:作为根树,需要继续处理其左右子树。

对于前,中,后序遍历代码基本一致,仅有少量改动,类似于写递归代码的体验。

代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    class Entry {
        TreeNode node;
        boolean flag;
        
        Entry(TreeNode node, boolean flag) {
            this.node = node;
            this.flag = flag;
        }
    }
    
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null) return new ArrayList<>();
        
        LinkedList<Integer> res = new LinkedList<>();
        LinkedList<Entry> stack = new LinkedList<>();
        stack.push(new Entry(root, false));
        while(!stack.isEmpty()) {
            Entry entry = stack.pop();
            TreeNode node = entry.node;
            boolean flag = entry.flag;
            if(flag) {
                res.add(node.val);
            } else {
                // 前中后序遍历只有这里稍微不同。
                stack.push(new Entry(node, true));
                if(node.right != null) stack.push(new Entry(node.right, false));
                if(node.left != null) stack.push(new Entry(node.left, false));
            }
        }
        
        return res;
    }
}
结果

在这里插入图片描述

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

相关推荐

输出二叉树后序遍历的逆序

较难较易混淆的二叉树部分经典例题,不会的童鞋~~

C语言版:二叉树的遍历方式和逆序

C语言版:数据结构中的二叉树,先序遍历,中序遍历,后序遍历,以及它们的逆序。 文章目录二叉树的遍历一、栈的运用二、遍历方式1.先序遍历2.中序遍历3.后序遍历代码实现 二叉树的遍历 二叉树的遍历方式:先序遍历:头左右,中序遍历:左头右, 后续遍历:左右头 的规则, 下面是本篇文章的二叉树的图。 提示:以下是本篇文章正文内容,下面案例可供参考 一、栈的运用 栈的操作规则:先进后出,比如说进制转化也是栈的应用,前面文章有介绍关于进制转化,二叉树的逆序可以运用栈。 二、遍历方式 1.先序遍历 代码如下(示

m0_53318344的博客 2209

吉林大学2016级唐班c语言期末考试B卷

` #include<stdio.h> #include<stdlib.h> //双指针法,每次从a,b中选一个最大的数,从后向前一次放在数组a中 int merge(int *a,int m,int *b,int n){ int i=m-1,j=n-1,k=m+n-1; while(i>=0&&j>=0){ if(a[i]>b[j])a[...

weixin_42339173的博客 1195

二叉树的后序遍历的逆序输出

typedef struct BiTNode { ElemType data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; void PostOrder(BiTree T,SqStack &S) { if(T!=NULL) { reverse_PostOrder(T->lchild); reverse_PostOrder(T->rchild); Push(S,T->data); } } void Pri.

vener_的博客 4469

基于Ultralytic实现多路摄像头目标检测

基于Ultralytic实现多路摄像头目标检测前面的文章分享了单路摄像头画面的YOLO目标检测,这篇文章主要分享一下多路摄像头画面的实时YOLO目标检测。测试环境在Windows系统下进行。

qq_57674776的博客 939

Coze+剪映小助手实战:5分钟搞定视频草稿创建工作流(附常见错误排查)

本文详细介绍了如何利用Coze平台与剪映小助手,通过create_draft接口快速搭建自动化视频草稿创建工作流。文章从核心价值、零基础搭建步骤、运行验证到深度错误排查,手把手教你5分钟内实现视频项目参数预设的标准化与自动化,显著提升短视频创作与团队协作效率。

oil88的博客 549

逆后序遍历实现二叉树的后序遍历

1、二叉树的遍历采用递归实现是比较简单的。

2613

Win11 C盘瘦身终极指南:哪些能删/能移/不能碰?附详细目录清单

本文提供了一份详细的Win11 C盘瘦身终极指南,清晰区分了可安全删除、适合迁移以及绝对不能触碰的系统目录。文章不仅列出了具体的文件夹清单与操作建议,还介绍了使用符号链接和Robocopy进行安全迁移的高阶方法,并附带了自动化脚本,帮助用户从根本上解决C盘空间不足的问题,同时确保系统稳定。

weixin_29246195的博客 1544

26、leetcode二叉树的前序遍历、二叉树的后序遍历

144. 二叉树的前序遍历 给定一个二叉树,返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? My Answer /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeN

KJ_Study的博客 344

STK与Matlab连接报错?手把手教你解决mexConnect函数执行问题(附完整避坑指南)

本文针对STK与Matlab连接时常见的“mexConnect函数执行”报错,提供了完整的诊断与解决方案。文章深入剖析了错误根源在于路径冲突或文件损坏,并手把手指导用户通过定位STK连接器文件、正确配置Matlab路径(包括使用addpath命令)以及执行初始化测试三步走策略,彻底解决问题。同时附上版本兼容性检查、安装避坑指南及构建稳健工作流的建议,帮助用户建立可靠的STK-Matlab联合仿真环境。

yolo5detector的博客 472

2025-08-19利用opencv检测图片中文字及图片的坐标

该代码实现了图片中中文文本的检测与位置计算功能。主要使用CnOcr库进行OCR识别,结合OpenCV和PIL库处理图像。功能包括:1)检测图片中的中文文本及位置坐标;2)计算每个文本的像素宽度和高度;3)在原图上绘制文本边界框并标注识别结果。代码通过put_chinese_text函数解决中文显示问题,最终输出各文本内容、坐标位置及尺寸信息。适用于需要获取图片中文字精确位置的应用场景。

m0_58149406的博客 394

树--二叉树的后序遍历

[145. Binary Tree Postorder Traversal(https://leetcode.com/problems/binary-tree-postorder-traversal/) 题目描述 二叉树的后序遍历 思想 (递归) (迭代) 先找到后序遍历的逆序根右左,然后再求得后序遍历。 解法1 左右根,递归。 # Definition for a binary tre...

lgy54321的博客 384

【YOLOv12改进trick】高效多尺度卷积注意力EMCAD_Block模块引入YOLOv12,实现涨点和效率提升,含创新点Python代码

EMCAD引入YOLOv12模块,实现高效多尺度注意力模块引入到YOLOv12中的快速涨点及效率提升

向上生长的程序媛的博客 851

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

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

qq_40263592的博客 1391

生信技能53 - WisecondorX自动化批量npz转换和reference构建

wiseconrdoX分析CNV适用于CNVseq、NIPT和WGS等项目。

LittleComputerRobot的博客 465

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

LeetCode 145 二叉树的后序遍历 Java

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

qq_29061435的博客 222

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

jre9下载 jdk9

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

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

力扣[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

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

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

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

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

LeetCode145-二叉树的后序遍历

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

sk18192449347的博客 217

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

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

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

2401_82472941的博客 635

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
上一篇: Leetcode 144. 二叉树的前序遍历
下一篇: Leetcode 173. 二叉搜索树迭代器
一纸浮萍
博客等级 码龄9年 11粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值