力扣刷题 二叉树遍历的统一迭代法

题干

给定一个二叉树的根节点 root ,返回 它的 前中后序 遍历 。

示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

解题思路

上一次我们使用了迭代法来实现前中后序遍历,但是每一种遍历的访问和处理顺序不同,导致代码书写风格不同,不像是递归法,实现了其中的一种遍历方式,其他两种只要稍稍改一下节点顺序就可以了。

但其实针对三种遍历方式,使用迭代法是可以写出统一风格的代码的。下面我们就来实现一下。

我们以中序遍历为例,我们之前提到使用栈的话,无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)顺序不一致的情况。

事实上,访问这个操作是持续进行的,而处理节点则是需要时机的,在中序遍历中,时机就是遍历到叶子节点。关键是如何把处理节点和访问节点都用栈的逻辑解决,之前的迭代法中,用到了指针来帮助访问和处理。

我们将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。其实每一个节点都是需要处理的,只是时机未到,而做的标记则可以帮助我们判断处理节点的时机。

如何标记呢,就是将要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法。

添加左节点和右节点的时候,空节点不入栈,这样遇到空指针即代表遇到叶子节点,到了处理节点的时机。

中序遍历

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if(root != NULL) st.push(root);while(!st.empty()){TreeNode* node =st.top();//如果没有遇到标记,则访问if(node != NULL){//先弹出来,避免干扰了左中右的顺序st.pop();//如果右子树不是空节点,则入栈if(node->right) st.push(node->right);//将中节点入栈st.push(node);// 做标记,表示待处理st.push(NULL);//如果左子树不是空节点,则入栈 if(node->left) st.push(node->left);}//当遇到标记使,开始处理节点else{//把标记NULL弹出st.pop();//取出节点放入结果数组node = st.top();st.pop();result.push_back(node->val);}}return result;}
};

而前序和后序遍历只需要改变访问的顺序即可

前序遍历

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();if (node->right) st.push(node->right);  // 右if (node->left) st.push(node->left);    // 左st.push(node);                          // 中st.push(NULL);} else {st.pop();node = st.top();st.pop();result.push_back(node->val);}}return result;}
};

后序遍历

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();st.push(node);                          // 中st.push(NULL);if (node->right) st.push(node->right);  // 右if (node->left) st.push(node->left);    // 左} else {st.pop();node = st.top();st.pop();result.push_back(node->val);}}return result;}
};

这样此时我们写出了统一风格的迭代法,不用在纠结于前序写出来了,中序写不出来的情况了。

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

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

相关文章

WebGL BabylonJS GUI 如何创建连接模型的按钮

如图所示&#xff1a; 方法&#xff1a; createGUI(mesh: BABYLON.Mesh, title: string, index: number) {const advancedTexture AdvancedDynamicTexture.CreateFullscreenUI(UI)const rect new Rectangle()rect.width 100pxrect.height 40pxrect.thickness 0advancedT…

101. 对称二叉树及同类题

101. 对称二叉树 力扣题目链接(opens new window) 给定一个二叉树&#xff0c;检查它是否是镜像对称的。 递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNo…

【python从入门到精通】-- 第四战:语句汇总

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

【NUCLEO-G071RB】001——开发板开箱

NUCLEO-G071RB&#xff1a;001——开发板开箱 打开包装开发板概述开始上手系统需求开发工具链 其他 打开包装 包装里包含一张纸片和一块开发板&#xff0c;这张纸片对开发板做了最基础的介绍。 开发板概述 板载STM32G071RBT6单片机&#xff0c;64pins&#xff1a; CPU&…

Day84:服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测

目录 端口协议-口令爆破&未授权 弱口令爆破 FTP&#xff1a;文件传输协议 RDP&#xff1a;Windows远程桌面协议 SSH&#xff1a;Linux安全外壳协议 未授权案例(rsync) 桌面应用-QQ&WPS&Clash QQ RCE 漏洞复现 WPS RCE 漏洞复现 Clas* RCE 漏洞复现 知识点…

【C++学习】哈希的应用—位图与布隆过滤器

目录 1.位图1.1位图的概念1.2位图的实现3.位图的应用 2.布隆过滤器2.1 布隆过滤器提出2.2布隆过滤器概念2.3如何选择哈希函数个数和布隆过滤器长度2.4布隆过滤器的实现2.4.1布隆过滤器插入操作2.4.2布隆过滤器查找操作2.4.3 布隆过滤器删除 2.5 布隆过滤器优点2.6布隆过滤器缺陷…

thinkphp6入门(21)-- 如何删除图片、文件

假设文件的位置在 /*** 删除文件* $file_name avatar/20240208/d71d108bc1086b498df5191f9f925db3.jpg*/ function deleteFile($file_name) {// 要删除的文件路径$file app()->getRootPath() . public/uploads/ . $file_name; $result [];if (is_file($file)) {if (unlin…

一文介绍回归和分类的本质区别 !!

文章目录 前言 1、回归和分类的本质 &#xff08;1&#xff09;回归&#xff08;Regression&#xff09;的本质 &#xff08;2&#xff09;分类&#xff08;Classification&#xff09;的本质 2、回归和分类的原理 &#xff08;1&#xff09;回归&#xff08;Regression&#x…

基于离散差分法的复杂微分方程组求解matlab数值仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于离散差分法的复杂微分方程组求解.“连续微分方程”到“离散微分方程”到“差分方程”&#xff0c;离散微分方程&#xff0c;变成差分方程。建立差分方程时&am…

FPGA高端图像处理开发板-->鲲叔4EV:12G-SDI、4K HDMI2.0、MIPI等接口谁敢与我争锋?

目录 前言鲲叔4EV----高端FPGA图像处理开发板核心板描述底板描述配套例程源码描述配套服务描述开发板测试视频演示开发板获取 前言 在CSDN写博客传播FPGA开发经验已经一年多了&#xff0c;帮助了不少人&#xff0c;也得罪了不少人&#xff0c;有的人用我的代码赢得了某些比赛、…

open-cd框架调试记录

源于论文Changer: Feature Interaction Is What You Need forChange Detection 源码位置&#xff1a;open-cd/README.md at main likyoo/open-cd (github.com) 同样是基于MMSegmentation框架的代码&#xff0c;不符合本人编程习惯所以一直也没有研究这东西&#xff0c;近期打…

函数重载和引用【C++】

文章目录 函数重载什么是函数重载&#xff1f;函数重载的作用使用函数重载的注意点为什么C可以函数重载&#xff0c;C语言不行&#xff1f; 引用什么是引用&#xff1f;引用的语法引用的特点引用的使用场景引用的底层实现传参时传引用和传值的效率引用和指针的区别 函数重载 什…