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

前言

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

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;
    }

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

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

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA】 javaSE中的数组|数组的概念使用

数组的概念 什么是Java中的数组 数组&#xff1a;可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。在java中&#xff0c;包含6个整形类型元素的数组&#xff0c;可以看做是酒店中连续的6个房间. 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3…

哪些情况下需要使用爬虫IP

不知道小伙伴们有没有遇到过这种场景&#xff1a;上网闲逛&#xff0c;看一些搞笑的视频或者想下载一些酷炫的文件&#xff0c;正点击呢&#xff0c;结果却发现被网站限制了&#xff0c;无法访问或者下载&#xff1f; 别急&#xff0c;今天我来告诉大家&#xff0c;如何借助使…

【JavaEE初阶】博客系统后端

文章目录 一. 创建项目 引入依赖二. 设计数据库三. 编写数据库代码四. 创建实体类五. 封装数据库的增删查改六. 具体功能书写1. 博客列表页2. 博客详情页3. 博客登录页4. 检测登录状态5. 实现显示用户信息的功能6. 退出登录状态7. 发布博客 一. 创建项目 引入依赖 创建blog_sy…

yolov3-spp 训练结果分析:网络结果可解释性、漏检误检分析

1. valid漏检误检分析 ①为了探查第二层反向找出来的目标特征在最后一层detector上的意义&#xff01;——为什么最后依然可以框出来目标&#xff0c;且mAP还不错的&#xff1f; ②如何进一步提升和改进这个数据的效果&#xff1f;可以有哪些优化数据和改进的地方&#xff1f;让…

页面技术基础-html

页面技术基础-html 环境准备&#xff1a;在JDBC中项目上完成代码定义 1. 新建一个 Module:filr->右键 -》Module -》Java-》next->名字(html_day1)->finish 2. 在 Moudle上右键-》第二个选项&#xff1a;add framework .. -> 选择JavaEE下第一个选项 Web Apllicat…

计及需求响应和电能交互的多主体综合能源系统主从博弈优化调度策略(Matlab代码实现)

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

通向架构师的道路之apache_tomcat_https应用

一、总结前一天的学习 通过上一章我们知道、了解并掌握了Web Server结合App Server是怎么样的一种架构&#xff0c;并且亲手通过Apache的Http Server与Tomcat6进行了整合的实验。 这样的架构的好处在于&#xff1a; 减轻App Server端的压力&#xff0c;用Web Server来分压…

python——案例8:设定列表:listl=[0,1,2,3,4,5],求列表之和

案例8&#xff1a;设定列表&#xff1a;listl[0,1,2,3,4,5],求列表之和total0 list1[0,1,2,3,4,5] #列表lis1for ele in range(0,len(list1)):totaltotallist1[ele] print("列表中元素之和&#xff1a;",total) #输出结果

13 springboot项目——准备数据和dao类

13.1 静态资源下载 https://download.csdn.net/download/no996yes885/88151513 13.2 静态资源位置 css样式文件放在static的css目录下&#xff1b;static的img下放图片&#xff1b;template目录下放其余的html文件。 13.3 创建两个实体类 导入依赖&#xff1a;lombok <!…

1400*C. Computer Game

Example input 6 15 5 3 2 15 5 4 3 15 5 2 1 15 5 5 1 16 7 5 2 20 5 7 3 output 4 -1 5 2 0 1 解析&#xff1a; k个电&#xff0c; 第一种为 k>a 时&#xff0c;只玩游戏 k-a; 第二种&#xff0c;k>b,一边玩一边充电 k-b 问完成n轮游戏的情况下&#xff0c;优先第…

性能优化点

Arts and Sciences - Computer Science | myUSF 索引3层&#xff08;高度为3&#xff09;一般对于数据库地址千万级别的表 大于2000万的数据进行分库分表存储 JVM整体结构及内存模型 JVM调优&#xff1a;主要为减少FULL GC的执行次数或者减少FULL GC执行时间 Spring Boot程序…

摄像机sd卡格式化怎么恢复数据?简单五步轻松解决

在使用摄像机时&#xff0c;有时不慎将SD卡格式化&#xff0c;导致重要的照片或视频文件丢失。然而&#xff0c;不必惊慌&#xff0c;本文将详细解释如何恢复被格式化的摄像机SD卡上的数据&#xff0c;可通过下面提供的五步&#xff0c;轻松解决数据丢失问题&#xff0c;以确保…

在OK3588板卡上部署模型实现人工智能OCR应用

一、主机模型转换 我们依旧采用FastDeploy来部署应用深度学习模型到OK3588板卡上 进入主机Ubuntu的虚拟环境 conda activate ok3588 安装rknn-toolkit2&#xff08;该工具不能在OK3588板卡上完成模型转换&#xff09; git clone https://github.com/rockchip-linux/rknn-to…

【云原生】Kubernetes中deployment是什么?

目录 Deployments 更新 Deployment 回滚 Deployment 缩放 Deployment Deployment 状态 清理策略 金丝雀部署 编写 Deployment 规约 Deployments 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。 你负责描述 Deployment 中的 目标状态&#xff0c;而 De…

基于RK3588+FPGA+AI算法定制的智慧交通与智能安防解决方案

随着物联网、大数据、人工智能等技术的快速发展&#xff0c;边缘计算已成为当前信息技术领域的一个热门话题。在物联网领域&#xff0c;边缘计算被广泛应用于智慧交通、智能安防、工业等多个领域。因此&#xff0c;基于边缘计算技术的工业主板设计方案也受到越来越多人的关注。…

python-爬虫作业

# -*- coding:utf-8 -*-Author: 董咚咚 contact: 2648633809qq.com Time: 2023/7/31 17:02 version: 1.0import requests import reimport xlwt from bs4 import BeautifulSoupurl "https://www.dygod.net/html/gndy/dyzz/" hd {user-Agent:Mozilla/4.0 (Windows N…

【雕爷学编程】Arduino动手做(180)---Seeeduino Lotus开发板2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

学习系统编程No.33【生产消费模型】

引言&#xff1a; 北京时间&#xff1a;2023/7/22/14:27&#xff0c;现实和预期往往相差是巨大的&#xff0c;哈哈哈&#xff01;白天睡不醒&#xff0c;晚上睡不着&#xff0c;就像一个夜猫子一样。熬夜耍手机&#xff0c;我真的是专业的&#xff0c;已经连续好久没有正常睡过…

DAY56:单调栈(二)下一个最大元素Ⅱ(环形数组处理思路)

文章目录 思路写法1完整版环形数组处理&#xff1a;i取模&#xff0c;遍历两遍写法2完整版&#xff08;环形数组推荐写法&#xff09;debug测试&#xff1a;逻辑运算符短路特性result数组在栈口取元素&#xff0c;是否会覆盖原有数值&#xff1f; 给定一个循环数组 nums &#…

Unity 性能优化五:渲染模块压力

CPU压力 Batching 在GPU渲染前&#xff0c;CPU会把数据按batch发送给GPU&#xff0c;每发送一次&#xff0c;都是一个drawcall&#xff0c;GPU在渲染每个batch的时候&#xff0c;会切换渲染状态&#xff0c;这里的渲染状态指的是&#xff1a;影响对象在屏幕上的外观的渲染属性…