【C++】非递归实现二叉树的前中后序遍历

news2024/11/29 12:51:19

​🌠 作者:@阿亮joy.
🎆专栏:《吃透西嘎嘎》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
在这里插入图片描述

目录

    • 👉二叉树的前序遍历👈
    • 👉二叉树的中序遍历👈
    • 👉二叉树的后序遍历👈
    • 👉总结👈

👉二叉树的前序遍历👈

前序遍历的顺序是根、左子树、右子树。那么首先访问的一定是左路节点,再来访问左路节点的右子树。而访问左路节点的右子树又可以看成一个子问题,那么就能像递归访问整棵树了。

思路:

  • 想定义一个栈st、一个vector v和一个TreeNode* curcur初始化为root
  • cur不为空或者st不为空时,while继续。while循环里做一下操作:左路节点入栈的同时尾插到v中,那么左路节点就访问完了。然后取出栈顶节点top,将cur置为top->right,这样就可以转化成子问题去访问左路节点的右子树了。
  • cur不为空表示要访问一棵树,st不为空表示还有左路节点的右子树没有访问。两个同时为空时,while循环结束,得到正确的前序遍历。
  • 注:一个节点出栈意味着这个节点及其左子树已经访问完了,还剩右子树没有访问。

在这里插入图片描述

class Solution 
{
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        // cur 不为空表示要访问一棵树
        // st 不为空表示还有右子树没有访问
        while(cur || !st.empty())
        {
            // 开始访问整棵树
            // 1.访问左路节点
            while(cur)
            {
                v.push_back(cur->val);
                st.push(cur);
                cur = cur->left;
            }

            // 转化成子问题:访问左路节点的右子树
            TreeNode* top = st.top();
            st.pop();

            cur = top->right;   // 子问题访问右子树
        }

        return v;
    }
};

在这里插入图片描述

👉二叉树的中序遍历👈

中序遍历的顺序是左子树、根、右子树。首先,和中序遍历一样的是左路节点入栈,入栈的同时不能访问该节点,即不能将节点的值尾插到vector中。当左路节点出栈时,表示当前节点的左子树已经访问完了,开始访问当前节点及其右子树。

class Solution 
{
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            // 1.左路节点入栈
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            // 2.当左路节点出栈时,表示左子树已经访问过了,应该
            // 访问这个节点和它的右子树
            TreeNode* top = st.top();
            st.pop();
            v.push_back(top->val);  // 访问这个节点

            cur = top->right;   // 转化成子问题访问右子树
        }

        return v;
    }
};

在这里插入图片描述

👉二叉树的后序遍历👈

后序遍历的顺序是左子树、右子树、根,需要将左子树和右子树访问完了,才能访问根。如果栈顶节点为空或者栈顶节点的右子树已经访问过了,就可以访问栈顶节点了。为了知道是否已经访问过栈顶节点的右子树,我们可以通过prev来记录上一次访问的节点。当prev等于top->right时,表示栈顶节点的右子树已经访问过了,可以弹出栈顶节点并访问它。

在这里插入图片描述

class Solution 
{
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        vector<int> v;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* prev = nullptr;

        while(cur || !st.empty())
        {
            // 左路节点入栈
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }

            TreeNode* top = st.top();   // 取栈顶节点但不pop

            // 栈顶节点右子树为空或者上一次访问的节点是top右子树的根,说明右子树已经访问过了
            // 可以访问栈顶节点,否则转换成子问题访问top的右子树
            if(top->right == nullptr || top->right == prev)
            {
                st.pop();
                v.push_back(top->val);
                prev = top;
                cur = nullptr;  // cur为空表示弹出的栈顶节点没有右子树或者右子树已经访问过了
            }
            else
                cur = top->right;
        }

        return v;
    }
};

在这里插入图片描述

👉总结👈

本篇的非递归实现二叉树的前中后序遍历都差不多是一个思路,左路节点先入栈。最大的区别就是栈顶节点的访问时机不同。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️

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

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

相关文章

如何运营个人技术博客

前言 本篇和大家聊聊如何运营个人技术博客&#xff0c;定位下做技术写作的目的&#xff0c;有哪些交流平台和输出方式&#xff0c;如何把控内容质量&#xff0c;整理了一些写作技巧和自己常用的写作工具&#xff0c;最后分享下如何在有限的时间里合理安排保证写作与工作的平衡。…

第九届蓝桥杯省赛 C++ A组 - 付账问题

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;蓝桥杯题解集合 &#x1f4dd;原题地址&#xff1a;付账问题 &#x1f4e3;专栏定位&#xff1a;为想考甲级PAT的小伙伴整理常考算法题解&#xff0c;祝大家…

理解CSS

CSS 作为前端技术栈中关键一环&#xff0c;对页面元素及样式呈现起到了直接作用。本节课旨在通过对 CSS 的工作流程及原理、页面中 CSS 使用方法等详细解读&#xff0c;帮助前端新手建立对 CSS 的全面而深刻的认知。 CSS概念 CSS 即 Cascading Style Sheets&#xff0c;是用来…

认识涤生大数据的几个月,彻底改变了我

1自我介绍 大家好&#xff0c;我是泰罗奥特曼&#xff0c;毕业于东北的一所不知名一本大学&#xff0c;学校在一个小城市里面&#xff0c;最热闹的地方是一个四层楼的商城&#xff0c;专业是信息管理与信息系统&#xff0c;由于是调剂的&#xff0c;所以我也不知道这个专业是干…

[JavaEE]阻塞队列

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录: 1.阻塞队列的概念 2.标准库中的阻塞队列 3.生产者…

1999-2019年全国、各省市直辖区居民收入和消费支出情况面板数据

1999-2019年全国、各省市直辖区居民收入和消费支出情况面板数据 1、时间&#xff1a;1999-2019年 2、指标&#xff1a; 可支配收入、城镇居民家庭平均每人全年消费性支出、食品消费支出、医疗保健消费支出、农村居民家庭人均纯收入、农村居民家庭平均每人生活消费支出、食品…

【Unity URP】设置光源层Light Layers

光源层 (Light Layers) 功能允许配置某些光源仅影响特定的游戏对象。 此功能可以用于加亮在暗处的物体。 1.开启光源层&#xff0c;并设置光源层名称 在URP资源中&#xff0c;点击Lighting右侧的垂直省略号图标 (⋮)&#xff0c;勾选Show Additional Properties&#xff0c…

【已解决】WARNING: Ignoring invalid distribution xxx

问题解决方案解释问题 WARNING: Ignoring invalid distribution -umpy (c:\users\xxx\appdata\roaming\python\python36\site-packages) 解决方案 在报错的路径下(c:\users\xxx\appdata\roaming\python\python36\site-packages)&#xff0c;找到~对应文件夹&#xff0c;此处…

Pytorch实战笔记(1)——BiLSTM 实现情感分析

本文展示的是使用 Pytorch 构建一个 BiLSTM 来实现情感分析。本文的架构是第一章详细介绍 BiLSTM&#xff0c;第二章粗略介绍 BiLSTM&#xff08;就是说如果你想快速上手可以跳过第一章&#xff09;&#xff0c;第三章是核心代码部分。 目录1. BiLSTM的详细介绍2. BiLSTM 的简单…

【三年面试五年模拟】算法工程师的独孤九剑秘籍(第十二式)

Rocky Ding公众号&#xff1a;WeThinkIn写在前面 【三年面试五年模拟】栏目专注于分享AI行业中实习/校招/社招维度的必备面积知识点与面试方法&#xff0c;并向着更实战&#xff0c;更真实&#xff0c;更从容的方向不断优化迭代。也欢迎大家提出宝贵的意见或优化ideas&#xff…

【算法】二叉树

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录二叉树数组转化为二叉树二叉树转化为二叉链表二叉树的遍历排序二叉树BST&#xff08;二叉搜索树&…

新思路dp

参考文章思路&#xff1a;点我 题&#xff1a;C. Count Binary Strings 前言&#xff1a;嗯,今天做这个题的时候&#xff0c;想了一堆乱七八糟的解法&#xff0c;想记录一下hhhhhh。 题意&#xff1a;输入以类似于邻接表的形式给出字符串&#xff08;只由000和111组成&#…

深入理解MySQL中的bin log、redo log、undo log

bin log&#xff08;二进制日志&#xff09; 什么是bin log&#xff1f; 记录数据库执行的写入性操作信息&#xff0c;以二进制的形式保存在磁盘中。 由服务层产生&#xff0c;所有储存引擎都支持。 bin log属于逻辑日志。 bin log日志有三种格式&#xff1a;STATMENT、ROW、M…

详解数据库的锁机制及原理

详解数据库的锁机制及原理1.数据库锁的分类2.行锁共享锁排他锁更新锁3.意向锁4.锁机制解释数据库隔离级别1.数据库锁的分类 本图源自CSDN博主&#xff1a;Stephen.W 数据库锁一般可以分为两类&#xff0c;一个是悲观锁&#xff0c;一个是乐观锁 乐观锁一般是指用户自己实现的…

Java 中是如何获取 IP 属地的

细心的小伙伴可能会发现&#xff0c;抖音新上线了 IP 属地的功能&#xff0c;小伙伴在发表动态、发表评论以及聊天的时候&#xff0c;都会显示自己的 IP 属地信息下面&#xff0c;我就来讲讲&#xff0c;Java 中是如何获取 IP 属地的&#xff0c;主要分为以下几步 通过 HttpSer…

HuggingFace (transformers) 自定义图像数据集、使用 DeiT 模型、Trainer 进行训练回归任务

资料 Hugging Face 官方文档&#xff1a;https://huggingface.co/ Hugging Face 代码链接&#xff1a;https://github.com/huggingface/transformers 1. 环境准备 创建 conda 环境激活 conda 环境下载 transformers 依赖下载 transformers 中需要处理数据集的依赖下载 pytor…

win10录屏文件在哪?如何找到录制后的文件

在工作和学习中&#xff0c;我们会遇到需要使用录屏工具录制电脑屏幕的情况&#xff0c;很多小伙伴在录制完win10电脑屏幕之后&#xff0c;找不到录制的视频文件。win10录屏文件在哪&#xff1f;今天小编教大家如何找到电脑录屏文件和录制win10电脑屏幕的方法&#xff0c;如果您…

带你认识QOwnNotes

导读QOwnNotes 是一款自由而开源的笔记记录和待办事项的应用&#xff0c;可以运行在 Linux、Windows 和 mac 上。这款程序将你的笔记保存为纯文本文件&#xff0c;它支持 Markdown 支持&#xff0c;并与 ownCloud 云服务紧密集成。 QOwnNotes 的亮点就是它集成了 ownCloud 云服…

数据量大也不卡的bi软件有哪些?

用过数据分析软件的都知道&#xff0c;很多的软件在数据量不算特别大的时候还好&#xff0c;分析效率、响应速度都不慢&#xff0c;但一旦使用的数据量超过一定范围&#xff0c;系统就会明显变慢&#xff0c;甚至崩溃。随着企业业务的发展扩张&#xff0c;数据分析的精细化&…

Linksys WRT路由器刷入OpenWrt与原厂固件双固件及切换

Linksys路由器OpenWrt与原厂固件双固件刷入及切换双固件机制使用原厂固件刷其他固件使用原厂固件切换启动分区使用OpenWrt刷入Sysupgrade使用OpenWrt刷入Img使用OpenWrt切换分区通用的硬切换分区&#xff08;三次重启&#xff09;双固件机制 新机器默认有一个原厂固件&#xf…