二叉树的遍历(非递归版)

文章目录

  • 二叉树的前序遍历
  • 二叉树的中序遍历
  • 二叉树的后序遍历

正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默,忍不住分享一下给大家。 点击跳转到网站。

二叉树的前序遍历

在这里插入图片描述
用递归实现前序遍历非常简单,但是用非递归怎么实现呢?
在这里插入图片描述
比如说这样一棵树,前序遍历是先访问根,再访问左子树、右子树。
但是我们要实现非递归,所以我们肯定要记录每个节点,只有当这个节点,不然我们没办法回来访问右子树,所以我们可以用一个栈,然后一直找到最左边的节点,在把路上节点都push进栈。然后在访问右子树节点。

在这里插入图片描述
我们可以把前序遍历分为这样几个部分,我们每次取一个栈里面的元素,就代表我们已经访问过它的根和左子树了,只需要访问它的右子树就可以了,所以我们去到这个节点后直接pop掉就可以了。只不过我们在找最左边的节点的时候先把这个接点给访问了就可以了。

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;//root为空并且栈为空就结束while(root||st.size()){while(root){v.push_back(root->val);st.push(root);root = root->left;}root = st.top()->right;st.pop();}return v;}
};

二叉树的中序遍历

在这里插入图片描述
在这里插入图片描述
同样,我们还是给这样一颗树,中序遍历是要遍历左子树、根、右子树,以这样的次序来遍历。我们可以使用前序遍历的思路,只不过我们先不访问根,我们先找到最左边的节点,然后在访问右子树之前把根给访问了就可以了。

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

二叉树的后序遍历

在这里插入图片描述
在这里插入图片描述
还是这样一棵树,后序遍历是以左子树、右子树、根,这样的次序来进行遍历。我们会发现,后序遍历用前面两个的思路好像并不能够完成,因为我们访问了右子树会发现根没法访问了,而且我们没法先访问根,我们要先访问它的左子树和右子树然后才能访问根,这样前面的思路就用不了了。

但是我们可以用一个指针来记录上一个访问的节点,但是我们怎么知道这个节点的右子树访问过没有呢?

我们会发现如果当前节点的右子树==记录的上一个节点的指针时,就说明这个颗树的左右子树被访问完了,可以访问根了,或者它的右子树为空也说明可以访问根了,只不过我们在访问的时候,要更新一下prev指针,如果不是这两种情况就说明右子树存在,我们需要访问右子树,直接让当前节点指向它的右孩子就可以了。

ps:每次更新完成后要把cur置空,防止死循环。

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

那么今天的分享就到这里了,有什么不懂得可以私信博主,或者添加博主的微信,欢迎交流。

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

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

相关文章

ROSCon 2023 大会回顾

系列文章目录 文章目录 系列文章目录前言一、会议内容二、其他活动 前言 我们与 ROSCon 2023 全体 700 多名与会者的合影。 视频回放链接 一、会议内容 ROSCon 2023 是我们第十二届年度 ROS 开发者大会&#xff0c;于 2023 年 10 月 18 日至 20 日在路易斯安那州新奥尔良举行。…

【论文精读3】CasMVSNet

模型处理过程&#xff1a; 一. 问题引入 基于学习的MVS算法因为受到显存的限制&#xff0c;输出的深度图的空间分辨率只有输入图像的1/16大小&#xff08;长宽均为输入图像的1/4大小&#xff09;。以MVSNet为例&#xff0c;对于16001184大小的输入图像&#xff0c;需要构建hwD…

【机器学习Python实战】线性回归

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习python实战 欢迎订阅&#xff01;后面的内容会越来越有意思~ ⭐内容说明&#xff1a;本专栏主要针对机器学习专栏的基础内容进行python的实现&#xff0c;部分…

Web之CSS笔记

Web之HTML、CSS、JS 二、CSS&#xff08;Cascading Style Sheets层叠样式表&#xff09;CSS与HTML的结合方式CSS选择器CSS基本属性CSS伪类DIVCSS轮廓CSS边框盒子模型CSS定位 Web之HTML笔记 二、CSS&#xff08;Cascading Style Sheets层叠样式表&#xff09; Css是种格式化网…

浏览器页面被恶意控制时的解决方法

解决360流氓软件控制浏览器页面 提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、接受360安全卫士的好意&#xff08;尽量不要选&#xff09;二、拒绝360安全卫士的好意&#xff08;强烈推荐&#xff09;第…

Leetcode—876.链表的中间结点【简单】

2023每日刷题&#xff08;三十三&#xff09; Leetcode—876.链表的中间结点 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* middleNode(struct ListNode* head) {struct ListNod…

Redis持久化机制详解

使用缓存的时候&#xff0c;我们经常需要对内存中的数据进行持久化也就是将内存中的数据写入到硬盘中。大部分原因是为了之后重用数据&#xff08;比如重启机器、机器故障之后恢复数据&#xff09;&#xff0c;或者是为了做数据同步&#xff08;比如 Redis 集群的主从节点通过 …

传输层——TCP协议

文章目录 一.TCP协议二.TCP协议格式1.序号与确认序号2.窗口大小3.六个标志位 三.确认应答机制&#xff08;ACK&#xff09;四.超时重传机制五.连接管理机制1.三次握手2.四次挥手 六.流量控制七.滑动窗口八.拥塞控制九.延迟应答十.捎带应答十一.面向字节流十二.粘包问题十三.TCP…

字符串函数详解

一.字母大小写转换函数. 1.1.tolower 结合cppreference.com 有以下结论&#xff1a; 1.头文件为#include <ctype.h> 2.使用规则为 #include <stdio.h> #include <ctype.h> int main() {char ch A;printf("%c\n",tolower(ch));//大写转换为小…

vscode编写verilog的插件【对齐、自动生成testbench文件】

vscode编写verilog的插件&#xff1a; 插件名称&#xff1a;verilog_testbench,用于自动生成激励文件 安装教程&#xff1a;基于VS Code的Testbench文件自动生成方法——基于VS Code的Verilog编写环境搭建SP_哔哩哔哩_bilibili 优化的方法&#xff1a;https://blog.csdn.net…

Jenkins持续集成

1. 持续集成及Jenkins介绍 1.1. 软件开发生命周期 软件开发生命周期又叫做SDLC&#xff08;Software Development Life Cycle&#xff09;&#xff0c;它是集合了计划、开发、测试和部署过程的集合。如下图所示 &#xff1a; 需求分析 这是生命周期的第一阶段&#xff0c;根据…