leetcode145. 二叉树的后序遍历,递归法+迭代法,全过程图解+步步解析,一点点教会你迭代法后序遍历

leetcode145. 二叉树的后序遍历,递归法+迭代法

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
在这里插入图片描述
输入:root = [1,null,2,3]
输出:[3,2,1]

示例 2:
输入:root = []
输出:[]

示例 3:
输入:root = [1]
输出:[1]

递归法还是一如既往的简单。

postorder函数是递归函数,用于辅助实现后序遍历。它接收两个参数:一个指向当前节点的指针root和一个用于存储遍历结果的向量res。函数首先检查当前节点是否为空,如果是,则直接返回。如果不为空,则递归调用自身,先遍历左子树,再遍历右子树。在遍历完左右子树后,将当前节点的值添加到结果向量res中。

postorderTraversal函数是对外提供的公共接口,用于获取二叉树的后序遍历结果。它接收一个参数:一个指向二叉树根节点的指针root。函数首先初始化一个空的结果向量res,然后调用postorder函数进行后序遍历,并将遍历结果存储在res中。遍历完成后,返回这个结果向量。

整个实现过程是典型的递归方法,通过递归调用自身来遍历二叉树的每一个节点。递归的终止条件是当前节点为空,这时函数会返回而不执行任何操作。
在这里插入图片描述

class Solution {
public:void postorder(TreeNode *root, vector<int> &res) {if (root == nullptr) {return;}postorder(root->left, res);postorder(root->right, res);res.push_back(root->val);}vector<int> postorderTraversal(TreeNode *root) {vector<int> res;postorder(root, res);return res;}
};

二叉树后序遍历的迭代法相对前序和中序来说就要难一点了,

定义辅助栈:使用一个stack<TreeNode *>类型的栈stk来辅助遍历。

定义前一个访问节点:定义一个TreeNode *类型的指针prev,用来记录上一个被访问的节点。

迭代遍历:使用一个while循环,条件是root不为空或栈stk不为空。这个循环将一直执行,直到所有节点都被访问。

向左下推:内部的第一个while循环将root沿着左子树一直推到最底部,直到遇到空节点。每次迭代,都将当前节点压入栈中,并更新root为当前节点的左子节点。

处理当前节点:当左子树被完全遍历后,root将变为nullptr,此时从栈中弹出栈顶元素,即当前节点。

后序遍历条件判断
如果当前节点的右子节点为空,或者右子节点已经访问过(即root->right == prev),则将当前节点的值添加到结果向量res中,并将prev更新为当前节点,然后将root设置为nullptr,准备处理下一个节点。
如果当前节点的右子节点不为空且未访问过,则将当前节点再次压入栈中,并更新root为当前节点的右子节点,继续遍历右子树。
在这里插入图片描述
1.我们再以这个图为例,首先向左下推直到D,ABD都入栈了,这时候判断D的左子树为null,于是弹出栈顶D,D没有右子树,于是D首先被遍历进结果数组,并将前一个访问节点记录为D,将root变成null,方便处理下一个节点。

2.接下来弹出栈顶元素B,B有右节点且前一个访问节点不是B的右节点,所以把B再推入栈,访问B的右节点F

3.F有左节点,于是F入栈,E入栈,E没有左节点,E出栈。E也没有右节点,于是E第二个被遍历进结果数组,并将前一个访问节点记录为E,将root变成null,方便处理下一个节点。

4.再弹出栈顶元素F,F没有右节点,于是F第三个被遍历进结果数组,并将前一个访问节点记录为F,将root变成null,方便处理下一个节点。

5.再弹出栈顶元素B,B有右节点,但是!!前一个访问节点是B的右节点F,所以B第四个被遍历进结果数组,并将前一个访问节点记录为B,将root变成null,方便处理下一个节点。

依此类推遍历完全部节点DEFBHGICA。
做完此题,二叉树的中序遍历就再简单不过了,可以秒杀。
具体题目如下。

leetcode94二叉树的中序遍历

我也写了二叉树中序遍历的题解,可以去看看。相对二叉树的中序遍历,后序遍历的迭代法确实难了不少,值得反复学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/47365.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器系统盘存储不够,添加数据盘并挂载(阿里云)

目录 1.获取数据盘设备名称 2.为数据盘创建分区 3.为分区创建文件系统 4.配置开机自动挂载分区 阿里云数据盘挂载说明链接&#xff1a;在Linux系统中初始化小于等于2 TiB的数据盘_云服务器 ECS(ECS)-阿里云帮助中心 1.获取数据盘设备名称 sudo fdisk -lu 运行结果如下所示…

Preceptron感知机

前言 在上一章中&#xff0c;我们讨论了回归问题&#xff0c;主要的任务就是拟合出数据集分布的解析式。而这一次的学习中&#xff0c;我们将关注分类问题。 Classification classification分类有两种&#xff1a;二元分类和多类分类。 二元分类&#xff1a;预测二值目标&am…

k8s核心操作_存储抽象_K8S中使用ConfigMap抽取配置_实现配置热更新---分布式云原生部署架构搭建032

现在有个问题,是上面我们利用pv和pvc 就是持久卷 以及 持久卷申请,实现了对存储的,pod删除以后,对其使用的存储空间也进行了删除,那么还有个问题,对于redis这种我们希望,他的配置也管理起来. 比如这个redis的配置文件. 以后其他的配置文件也是这样. 使用配置文件的存储在k8s中…

Spring Boot 中使用 Resilience4j 实现弹性微服务的简单了解

1. 引言 在微服务架构中&#xff0c;服务的弹性是非常重要的。Resilience4j 是一个轻量级的容错库&#xff0c;专为函数式编程设计&#xff0c;提供了断路器、重试、舱壁、限流器和限时器等功能。 这里不做过多演示&#xff0c;只是查看一下官方案例并换成maven构建相关展示&…

Hadoop3:RPC通信原理及简单案例实现

一、场景介绍 我们知道&#xff0c;Hadoop中存在多种服务&#xff0c;那么&#xff0c;服务之间是如何通信的了&#xff1f; 比如&#xff0c;DN和NN之间如何通信&#xff1f; 这里&#xff0c;实际上是通过RPC实现进程间通信的了。 RPC属于Java网络编程范畴 需要编写客户端和…

AAD Connect自定义同步用户上云

使用场景&#xff1a;我想同步本地AD域的那些用户信息、账号上云端做SSO登录和权限管控&#xff0c;但是不希望使用快速上传一股脑传上去&#xff0c;所以使用自定义同步功能上传&#xff0c;这是一篇对AAD CONNECT这个应用的详解和配置步骤推荐 AD Connect如何自定义配置&…

隐性行为克隆——机器人的复杂行为模仿学习的新表述

介绍 论文地址&#xff1a;https://arxiv.org/pdf/2109.00137.pdf 源码地址&#xff1a;https://github.com/opendilab/DI-engine.git 近年来&#xff0c;人们对机器人学习进行了大量研究&#xff0c;并取得了许多成果。其中&#xff0c;模仿学习法尤其受到关注。这是一种从人…

iOS ------ 消息传递和消息转发

一&#xff0c;消息传递 在OC中&#xff0c;传递消息就是在对象上调用方法。 相对于C语言的方法就“静态绑定”的函数&#xff0c;在编译器就决定了运行时所要调用的函数。在OC中&#xff0c;如果向某对象传递消息&#xff0c;就会使用动态绑定机制来决定需要调用那个方法。调…

全球风味:红酒中的地域风情与特色

在红酒的世界里&#xff0c;每一滴琼浆玉液都承载着地域的风情与特色。它们不仅仅是葡萄酒&#xff0c;更是大自然的恩赐&#xff0c;是时间的馈赠&#xff0c;是人类智慧的结晶。今天&#xff0c;就让我们一起走进红酒的世界&#xff0c;感受那些来自不同地域的风情与魅力。 …

ROS2入门到精通—— 2-6 ROS2实战:可调节纯跟踪算法(局部规划)

1 Regulated Pure Pursuit 纯追踪算法变体&#xff1a;调节纯追踪算法 将自适应纯追踪&#xff08;Adaptive Pure Pursuit&#xff09;算法的特性与围绕线性速度的规则相结合&#xff0c;重点关注消费类、工业和服务型机器人的需求。我们还实现了几种常识性的安全机制&#xf…

业务终端动态分配IP-DHCP技术、DHCP中继技术

一、为什么需要DHCP? 1、许多设备(主机、无线WiFi终端等)需要动态地址的分配; 2、人工手工配置任务繁琐、容易出错,比如:IP地址冲突; 3、网络规模扩大、复杂度提高,网络配置越来越复杂,计算机的位置变化和数量超过可分配IP地址的数量,造成IP地址变法频繁以及IP地址…

Monaco 使用 DocumentHighlightProvider

Monaco 中有一个文字高亮的功能&#xff0c;就是选中一个单词&#xff0c;会高亮文字文档中所有出现该单词的位置&#xff0c;效果如下&#xff1a; Monaco 默认就有这个功能&#xff0c;可以根据具体需求进行定制。通过 registerDocumentHighlightProvider 进行注册 实现 pro…

【Java数据结构】初始线性表之一:链表

为什么要有链表 上一节我们描述了顺序表&#xff1a;【Java数据结构】初识线性表之一&#xff1a;顺序表-CSDN博客 并且进行了简单模拟实现。通过源码知道&#xff0c;ArrayList底层使用数组来存储元素。 由于其底层是一段连续空间&#xff0c;当在ArrayList任意位置插入或者…

代码随想录二刷复习(二分法)

二分法模板&#xff1a; 1&#xff1a;左闭右闭区间写法 第一种写法&#xff0c;我们定义 target 是在一个在左闭右闭的区间里&#xff0c;也就是[left, right] &#xff08;这个很重要非常重要&#xff09;。 区间的定义这就决定了二分法的代码应该如何写&#xff0c;因为定…

vue 给特定满足条件的表单数据添加背景颜色,组件的 row-class-name

1、:row-class-name"tableRowClassName" 可为表格每行根据后面的函数绑定class名 <!-- 列表框 --><div class"tableList"><el-table :data"teamModelListTable" style"width: 100%"selection-change"handleSele…

el-table表格操作列错行处理

解决方法&#xff1a; <style>::v-deep .el-table th.el-table__cell > .cell {white-space: nowrap !important;} </style>

不想填邀请码?Xinstall来帮你,一键安装无忧愁

在这个快节奏的时代&#xff0c;每一个点击都承载着用户的期待与耐心。然而&#xff0c;在下载App的过程中&#xff0c;繁琐的邀请码填写往往成为了用户体验的一大障碍。你是否也曾经因为不愿填写邀请码而放弃了一款心仪的App&#xff1f;今天&#xff0c;就让我们一起走进Xins…

镜像与容器

Docker Image (镜像) Docker 镜像概念 Docker iamge 本质上是一个 read-only 只读文件&#xff0c;这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必需的文件。 可以把 Docker image 理解成一个模板&#xff0c;可以通过这个模板实例化出来很多…

【Datawhale AI 夏令营】入门lightgbm及特征工程进行实践

文章目录 1. LightGBM简介2. 导入必要的库3. 加载数据集4. 数据可视化4.1 不同类型对应目标值的柱状图4.2 特定ID的目标值折线图 5. 特征工程5.1 合并训练集和测试集并进行排序5.2 历史平移5.3 窗口统计5.4 数据切分5.5 确定输入特征 6. 模型训练与评估7. 结果展示 1. LightGBM…

一文看懂JTAG基本知识

文章目录 1、JTAG是什么?1.1边界扫描2、JTAG如何起作用?2.1 PC控制JTAG2.2 并行端口2.3 JTAG TAP控制器2.4 计算JTAG链中元件个数2.5 获得JTAG链上芯片的ID3、边界扫描3.1、SAMPLE3.2、边界扫描寄存器3.3、JTAG还可以做什么?参考资料:1、JTAG是什么? JTAG是20世纪80年代开…