二叉树的前,中,后序的非递归实现(c++)

news2024/11/15 7:10:02

前言

        对于二叉树来说,遍历它有多种方式,其中递归遍历是比较简单的,但是非递归的实现就有一定的难度,在这里介绍一种非递归实现二叉树遍历的方式。

1.前序遍历

        1.1思路

        其实对于二叉树的非递归实现,实际上就是用代码来模拟操作系统压栈和弹栈的过程。让我们一起来看看吧,首先将一棵树 分为左边节点和左边节点的右子树。如图:

        然后借助于一个栈,先将左边节点入栈,入栈时要将节点的值存到数组中。将左边节点全部入栈后,再来将左边节点的右子树入栈,重复上述过程。直至栈为空并且,当前的指针也为空,此时完成二叉树的前序遍历。如图: 

        1.2代码实现 

        

    vector<int> preorderTraversal(TreeNode* root)
    {
        vector<int> v;
        stack<TreeNode*> sT;
        //1.处理左边节点
        //2.处理左边节点的右子树
        TreeNode * cur = root;
        while(cur ||  !sT.empty()  )
        {
            while(cur)
            {
                //左边节点入栈
                sT.push(cur);
                v.push_back(cur->val);
                
                cur = cur -> left;
            }
            TreeNode* p = sT.top();
            sT.pop();
            cur = p -> right;
            //左边节点的右子树入栈
        }
        return v;
    }

2.中序遍历

        2.1思路        

        中序遍历的思路和前序遍历基本相同,就是此时左边节点入栈时不会将左边节点的val插到数组中,而是在栈中将节点的指针取出时再尾插到数组中。 

        2.2代码实现 

        

  vector<int> inorderTraversal(TreeNode* root) 
    {
        vector<int> ret;
        stack< TreeNode* > sT;
        TreeNode* cur = root;
        while(cur || !sT.empty())
        {
            //树的左边节点入栈
            while(cur)
            {
                sT.push(cur);
                cur = cur -> left;
            }
            //取出栈顶节点的指针
            //将栈顶节点指针的val尾插到数组中
            TreeNode * top = sT.top();
            sT.pop();
            //左边节点的右子树入栈
            cur = top -> right;
            ret.push_back(top->val);
        }
        return ret;
    }

3.后序遍历 

        3.1思路

        后序遍历沿用了中序遍历的思路,唯一不同的是将左边节点依次入栈后,出栈时先处理当前节点的左子树,然后将右子树入栈,等处理完右子树后再来处理当前节点。

        3.2代码实现 


    vector<int> postorderTraversal(TreeNode* root) 
    {
        TreeNode * cur = root;
        TreeNode * back = nullptr;//用来记录处理上一个节点
        vector<int> ret;
        stack<TreeNode*> sT;
        while(cur || !sT.empty() )
        {
            //左边节点入栈
            while(cur)
            {
                sT.push(cur);
                cur = cur->left;
            }
            //取出栈顶数据
            TreeNode* top = sT.top();
            
            if(top->right == nullptr || top->right == back)
            {
                ret.push_back(top->val);
                back = top;//记录处理过的节点
                sT.pop();
            }
            else
            {
                //左边节点的右子树入栈
                cur = top -> right;
            }
        }
        return ret;
    }

        后续遍历需要注意的是在什么时候来对当前节点进行处理,要先处理左右节点之后对当前节点进行处理,如果右节点为空很好办直接判断右节点为不为空就可以了,但是如果右节点不为空呢?怎么确保右节点已经处理过了再来对当前节点进行处理呢,这里提供一种较为简单的思路,通过一个指针来记录上次处理的节点,因为后序遍历总是按照左子树,右子树和根的处理顺序来的所以我们只需要处理比较上一个处理的节点是不是当前节点的右子树就可以知道 当前节点的右子树是否已经被处理过了,来判断当前节点是否需要处理。

        讲的不好,希望不要喷我。

 

 

 

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

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

相关文章

Spring中Bean的实例化详细流程

还是举个例子&#xff0c;我有一个朋友小汪他远赴南方某城市打工。然后安定下来后他的朋友很想来家里玩&#xff0c;但是呢我这个朋友家里搞的很乱&#xff0c;所以他不好意思请朋友来家里玩。这时我的另一个朋友说那请一个保姆把家里好好整理一下就可以了&#xff0c;然后给他…

【LeetCode】一、链表反转

题目 题目&#xff1a;给定单链表头节点&#xff0c;将单链表的链接顺序反转过来 例&#xff1a; 输入&#xff1a;1->2->3->4->5 输出&#xff1a;5->4->3->2->1 要求&#xff1a;按照两种方式实现 解决办法 方式一&#xff1a;&#xff08;直接迭…

腾讯云服务器CVM镜像操作系统大全_win_linux

腾讯云CVM服务器的公共镜像是由腾讯云官方提供的镜像&#xff0c;公共镜像包含基础操作系统和腾讯云提供的初始化组件&#xff0c;公共镜像分为Windows和Linux两大类操作系统&#xff0c;如TencentOS Server、Windows Server、OpenCloudOS、CentOS Stream、CentOS、Ubuntu、Deb…

大一python编程题库和答案,大一python基础编程题库

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;大一python编程题库和答案山东理工大学&#xff0c;大一python编程题库和答案解析&#xff0c;今天让我们一起来看看吧&#xff01; 单项选择题 第一章python语法基础 1. Python 3.x 版本的保留字总数是C A 27 …

Python(五十七)列表生成式

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Delphi 开发不一样的窗体标题栏:TTitleBarPanel

目录 TTitleBarPanel 的使用 TTitleBarPanel 的使用进阶 一、设置标题栏高度、颜色 二、个性化标题栏的关闭等按键 我们在用Delphi开发程序的时候&#xff0c;窗体的标题栏一般都是标准的windows标题栏&#xff0c;上面包括&#xff1a;程序图标、标题、最小化、最大化、关闭…

TypeC拓展设计方案|TypeC转HDMI设计方案|CS5261/CS5265芯片设计参数对比

集睿智远CS5261/CS5265都可以用于设计TypeC转HDMI方案&#xff0c;低成本TypeC扩展坞设计方案&#xff0c;而两者也有些差异&#xff1a;1.CS5261支持DP1.4输入&#xff0c;一个HDMI1.4输出&#xff0c;即HDMI输出为4K30HZ ;CS5265DP1.4到HDMI2.0转换芯片&#xff0c;即HDMI输出…

Linux之 环境变量

什么是环境变量 windows中也有个 Linux 环境变量 env linux和windows环境变量&#xff0c;功能类似的&#xff0c; windows系统的环境变量&#xff0c;在cmd中可以之间调用程序运行。这些程序的执行程序的路径&#xff0c;一般编辑在path变量中 环境变量都分全局的&#xff…

Android性能优化—ANR问题分析

一、ANR是什么&#xff1f; ANR(Application Not responding)&#xff0c;是指应用程序未响应&#xff0c;Android系统对于一些事件需要在一定的时间范围内完成&#xff0c;如果超过预定时间能未能得到有效响应或者响应时间过长&#xff0c;都会造成ANR。可以简单的理解为应用…

网络入侵探测器Pi.Alert

什么是 Pi.Alert &#xff1f; Pi.Alert 是 WIFI/LAN 入侵探测器。通过扫描连接到您的 WIFI/LAN 的设备&#xff0c;提醒您未知设备的连接。它还警告断开“始终连接”的设备。 Pi.Alert 使用了三种扫描方式 方式1&#xff1a;arp-scan。arp扫描系统实用程序用于使用 arp 帧搜索…

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

CommunityToolkit.Mvvm8.1 viewmodel使用-旧式写法

0.说明 CommunityToolkit.Mvvm8.1有一个重大更新的功能:源生成器功能,它极大简化我们的mvvm代码 但是本篇先总结一下原写法,下篇再总结源生成器功能 1.模型定义 必须继承:ObservableObject 2.viewmodel代码实现 几个关键点: SetProperty是给属性赋值,并且通知更改通知 But…

钉钉对接打通金蝶云星空获取流程实例列表详情(宜搭)接口与其他应收单接口

钉钉对接打通金蝶云星空获取流程实例列表详情&#xff08;宜搭&#xff09;接口与其他应收单接口 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台&#xff0c;提供PC版&#xff0c;Web版和手机版&#xff0c;有考…

Linux知识点 -- VS Code远程连接服务器协助开发

Linux知识点 – VS Code远程连接服务器协助开发 文章目录 Linux知识点 -- VS Code远程连接服务器协助开发一、VS Code的使用1.使用VS Code进行C语言编译与运行2.使用VS Code进行C代码的编译与运行 二、使用VS Code连接云服务器三、使用VS Code进行GDB调试 一、VS Code的使用 1…

Redis的基础知识

目录 一、什么是Redis 二、关于Redis的一些基本知识 &#xff08;1&#xff09;set命令 &#xff08;2&#xff09;get命令 三、Redis中的一些常用命令 &#xff08;1&#xff09;keys &#xff08;2&#xff09;exists &#xff08;3&#xff09;type &#xff08;4…

vite+typescript项目 :找不到模块“./***.vue”或其相应的类型声明——解决方案

vue3ts报错&#xff1a; 找不到模块“./App.vue”或其相应的类型声明。ts(2307) 解决方法&#xff1a; 1、在src文件夹找到 vite-env.d.ts 加入以下代码&#xff1a; declare module *.vue {import type { DefineComponent } from vueconst vueComponent: DefineComponent<…

Nodejs 第六章(npx)

npx是什么 npx是一个命令行工具&#xff0c;它是npm 5.2.0版本中新增的功能。它允许用户在不安装全局包的情况下&#xff0c;运行已安装在本地项目中的包或者远程仓库中的包。 npx的作用是在命令行中运行node包中的可执行文件&#xff0c;而不需要全局安装这些包。这可以使开…

手机python编程软件怎么用,手机python编程软件下载

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;手机python编程软件保存的代码在哪里&#xff0c;手机python编程软件怎么运行&#xff0c;现在让我们一起来看看吧&#xff01; 原标题&#xff1a;盘点几个在手机上可以用来学习编程的软件 前天在悟空问答的时候&#…

win上打包发包发布

地址 192.168.X.X 账号密码 zhanghaomima 连接方式&#xff1a; Win自带工具&#xff1a; 远程桌面连接 更新客户端代码 直接替换 D:\xmes\client3\elements 下的 cust-bundles 文件夹 更新mobile代码 直接替换 D:\xmes\mobile\scripts 下的fragments文件夹 更新服务端代…

【物理】带电粒子在磁场和电场中移动的 3D 轨迹研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…