二叉树深度优先搜索(非递归实现,迭代法)

目录

为什么可以用迭代法实现二叉树的前后中序遍历?

前序遍历

后序遍历

中序遍历


为什么可以用迭代法实现二叉树的前后中序遍历?

因为递归的实现本质是,每次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,这就是递归为什么可以返回上一层位置的原因。

所以我们可以用栈实现二叉树的前中后序遍历

前序遍历

前序遍历的顺序是中左右,我们需要设置一个节点指针用来表示此时遍历的节点,先将该节点指针初始化为根节点,然后判断该节点指针是否为空指针,如果为空指针,则返回结果。如果不为空,那么先把根节点放入栈中,然后设置循环直到栈为空时循环结束。循环中将栈顶元素放入结果数组中,并弹出。然后先把该节点的右子节点放入栈中(如果该子节点不为空),把左子节点也放入栈中,然后进行下一次循环,这样就可保证下次循环先处理的是左子节点。

具体代码:

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

后序遍历

后序遍历的顺序是左右中。由于前序遍历的顺序是中左右,我们如果交换左右子节点入栈顺序,就可以实现左右子节点的遍历顺序的交换。所以将前序遍历的左右子节点压栈语句交换位置,可以实现中右左遍历顺序,然后对最后的结果数组进行翻转就可以实现左右中遍历顺序,即后序遍历。

具体代码:

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> result;if(root == nullptr) return result;st.push(root);while(!st.empty()) {TreeNode* node = st.top();result.push_back(node->val);st.pop();if(node->left) st.push(node->left);if(node->right) st.push(node->right);}reverse(result.begin(), result.end());return result;}
};

中序遍历

在前序遍历中主要有两个操作:

处理:将元素放进result数组中

访问:遍历节点

前序遍历的顺序是中左右,先访问的是中间节点,要处理的元素也是中间节点,即要访问的元素和要处理的元素顺序是一致的

中序遍历的顺序是左中右,先访问的是二叉树顶部的节点,然后一层层向下访问,直到到达树左边的最底部,然后才开始把节点数值放进结果数组中,即处理顺序和访问顺序不一致

具体实现过程是:先设置循环直到栈为空结束循环,此时节点遍历完毕,返回结果数组。如果栈不为空,或者节点不为空则进入循环体内部,循环体内部需要先判断节点是否为空。如果不为空,就把该节点放入栈中,然后遍历下一个左节点(左)。如果节点为空,则将栈顶节点值放入结果数组中(中),然后弹出栈顶元素,同时遍历该节点的右子节点(右)。

具体代码:

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode* cur = root;while(!st.empty() || cur!=nullptr) {if(cur != nullptr) {st.push(cur);cur = cur->left;}else {TreeNode* node = st.top();st.pop();result.push_back(node->val);cur = node->right;}}return result;}
};

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

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

相关文章

web期末作业设计网页

设计一个网页作为期末作业是一个很好的机会来展示你的前端开发技能。以下是一些步骤和建议&#xff0c;帮助你完成这个项目&#xff1a; 1. 确定网页主题和目的 决定你的网页是关于什么的&#xff08;例如&#xff1a;个人博客、在线商店、公司网站、信息发布平台等&#xff…

国产车规MCU OTA方案总结

目录 1. 旗芯微FC4150 OTA 2. 云途YTM32B1MD OTA 3.小结 今天没有废话&#xff0c;啪一下很快&#xff0c;把目前接触到的国内带eFlash的车规MCU硬件OTA方案做一个梳理。 1. 旗芯微FC4150 OTA 旗芯微FC4150是基于ARM Cortex(快去审核下官网介绍&#xff0c;少了个T)-M4F内…

入门者必看-Ansible:自动化运维的利器

1. 引言 在当今快速变化的IT环境中&#xff0c;自动化成为了提升工作效率和确保系统一致性的重要手段。Ansible作为一个开源的自动化工具&#xff0c;因其简单易用、功能强大而广受欢迎。本文将深入探讨Ansible的概念、架构、体系结构、搭建过程、常用操作方式以及使用场景&…

openGauss Developer Day 2024丨MogDB实现数据库技术跨越,Ustore引擎革新存储新境界

openGauss Developer Day 2024 6月21日&#xff0c;openGauss Developer Day 2024在北京昆泰嘉瑞文化中心成功召开。大会聚集学术专家、行业用户、合作伙伴和开发者&#xff0c;共同探讨数据库面向多场景的技术创新&#xff0c;分享基于 openGauss 的行业联合创新成果及实践案例…

探索PHP中的魔术常量

PHP中的魔术常量&#xff08;Magic Constants&#xff09;是一些特殊的预定义常量&#xff0c;它们在不同的上下文中具有不同的值。这些常量可以帮助开发者获取文件路径、行号、函数名等信息&#xff0c;从而方便调试和日志记录。本文将详细介绍PHP中的魔术常量&#xff0c;帮助…

web前端——javaScript

目录 一、javaScript概述 1.javaScript历史 2.JavaScript与html,css关系 二、基本语法 ①放在head中 ②放在 body中 ③写在外部的.js文件中 1.变量 2.数据类型 3.算术运算符 4.逻辑运算符 5.赋值运算 6.逻辑运算符 7.条件运算符 8.控制语句 三、函数 1…

智能扫地机器人环境感知与地图构建优化方案

以下是一个针对智能扫地机器人程序中环境感知与地图构建问题的具体解决方案&#xff0c;参考了之前文章中的相关技术和信息&#xff1a; 智能扫地机器人环境感知与地图构建优化方案 一、引入高精度传感器 激光雷达&#xff08;LiDAR&#xff09;&#xff1a;使用高精度激光雷达…

模板语法轮播

1.常用的视图容器组件 view类似于div进行使用 <div></div><view></view> scroll-view实现滚动列表效果 <scroll-view scroll-y> <view></view> <view></view> <view></view> </scroll-view> …

数据库死锁解决

一、Oracle死锁查看和解决办法汇总 由于生产的tomcat 经常有假死问题&#xff0c;困扰很久&#xff0c;最后发现有死锁&#xff0c;解决办法分享 1.1、查看死锁 1.1.1、用dba用户执行以下语句 select username,lockwait,status,machine,program from v$session where sid in …

Arduino - 按钮 - 长按短按

Arduino - Button - Long Press Short Press Arduino - 按钮 - 长按短按 Arduino - Button - Long Press Short Press We will learn: 我们将学习&#xff1a; How to detect the button’s short press 如何检测按钮的短按How to detect the button’s long press 如何检测…

重大进展!微信支付收款码全场景接入银联网络

据中国银联6月19日消息&#xff0c;近日&#xff0c;银联网络迎来微信支付收款码场景的全面接入&#xff0c;推动条码支付互联互通取得新进展&#xff0c;为境内外广大消费者提供更多支付选择、更好支付体验。 2024年6月&#xff0c;伴随微信支付经营收款码的开放&#xff0c;微…

Docker部署Nginx+Keepalived

# 创建挂载路径 mkdir /data/nginx_keep/nginx/conf -p mkdir /data/nginx_keep/keepalived/vim nginx.conf user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {incl…

Rust: duckdb和polars读csv文件比较

一、文件准备 样本内容&#xff0c;N行9列的csv标准格式&#xff0c;有字符串&#xff0c;有浮点数&#xff0c;有整型。 有两个csv文件&#xff0c;一个大约是2.1万行&#xff1b;一个是64万行。 二、toml文件 [package] name "my_duckdb" version "0.1.0&…

opencv简单小项目

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了大量的图像和视频处理功能。使用OpenCV可以开发各种简单的小项目&#xff0c;例如&#xff1a; 图像基本操作&#xff1a; 读取和显示图像。调整…

弱监督学习

弱监督学习&#xff08;Weak Supervision&#xff09;是一种利用不完全、不精确或噪声数据进行模型训练的方法。以下是一些常用的弱监督方法及其原理&#xff1a; 1. 数据增强&#xff08;Data Augmentation&#xff09; 原理&#xff1a; 数据增强是一种通过增加训练数据的多…

区块链的历史和发展:从比特币到以太坊

想象一下&#xff0c;你住在一个小镇上&#xff0c;每个人都有一个大账本&#xff0c;记录着所有的交易。这个账本很神奇&#xff0c;每当有人买卖东西&#xff0c;大家都会在自己的账本上记一笔&#xff0c;确保每个人的账本都是一致的。这就是区块链的基本思想。而区块链的故…

HG/T 5838-2021金属骨架发泡橡胶复合密封板检测

金属骨架发泡橡胶复合密封板是指工作温度范围-40&#xff5e;140℃&#xff0c;峰值温度为150℃条件下使用的金属骨架发泡密封板。 HG/T 5838-2021金属骨架发泡橡胶复合密封板检测项目&#xff1a; 测试项目 测试标准 外观 HG/T 5838 厚度 HG/T 5838 压缩性能 GB/T 206…

VSCode安装OpenImageDebugger

VSCode安装OpenImageDebugger 1. 官网2. 编译2.1 依赖项2.2 编译 OpenImageDebugger2.3 配置 GDB 和 LLDB 3. 验证安装是否成功 1. 官网 下载路径&#xff1a;OpenImageDebugger 2. 编译 2.1 依赖项 官网上描述&#xff0c; Qt 5.15.1Python 3.10.12 这两个其实配置并不需…

【好物推荐】给大家安利一个liux运维全能脚本工具箱

前几天在开源社区冲浪的时候无意间逛到一个部署帖&#xff0c;里面提到了一个脚本&#xff0c;让我眼前一亮。 科技Lion的Shell脚本&#xff01;大家赶紧去体验学习一下&#xff0c;感觉写的还是不错的。 该工具是一款全能脚本工具箱&#xff0c;使用shell脚本编写。专为Linux服…

Jenkins多stage共享同一变量方式

在第一个stage中为这个变量赋值&#xff0c;在其它stage中使用这个变量 import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardCopyOption import groovy.json.JsonOutput import groovy.json.JsonSlurper// 共享的…