二叉树的循环问题

news2025/1/18 16:49:36

目录

一、二叉树的完全性检验

 二、前序遍历的非递归写法

三、中序遍历的非递归写法

四、后序遍历的非递归写法


一、二叉树的完全性检验

给定一个二叉树的 root ,确定它是否是一个 完全二叉树 。 在一个 完全二叉树 中,除了最后一个关卡外,所有关卡都是完全被填满的,并且最后一个关卡中的所有节点都是尽可能靠左的。它可以包含 1 到 2h 节点之间的最后一级 h 。

 

这道题目需要分阶段:将一颗完全二叉树看做两个阶段。

阶段一:此时的节点都是度为2的结点,当碰到第一个只有左子树没有右子树或者叶子结点,从该结点之后的结点应该都在二叉树。

阶段二:此时的节点全都是叶子结点,碰到一个反例直接return false。

当遇到一个结点只有右子树,那么直接return false。

所以首先判断树是否只有一个结点,root.left ==null&&root.right==null如果满足这个条件那么直接返回true。

主要就是根据层序遍历入队出队进行判断是否是完全二叉树,所以首先创建一个对列deque,将根节点入队,然后设置一个两边isSecondStep来判断是否在第二阶段。

然后进行出队并且将出队元素存储起来,然后进行判断现在是哪个阶段,这时是第一阶段,若左右子树都不为空,那么就让他们的左右子树入队即可。

 然后继续出队,这时还是第一阶段,左右子树都不为空,让他们的左右子树入队。

 然后继续出队,这时还是第一阶段,但是这个时候左子树不为空右子树为空,所以进入第二阶段设置isSecondStep为true,然后将左子树入队。

 这时在进入循环就是第二阶段了,判断每个出队元素的左右子树是否都为空,若不是那么立即返回false。进行到最后了就返回isSecondStep即可。

    public boolean isCompleteTree(TreeNode root) {
        if(root.left ==null&&root.right==null){
            return true;
        }
        Deque<TreeNode> deque = new LinkedList<>();
        deque.offer(root);
        boolean isSecondStep = false; 
        while(!deque.isEmpty()){
            TreeNode tmp = deque.poll();
            if(!isSecondStep) {
                if (tmp.right != null && tmp.left != null) {
                    deque.offer(tmp.left);
                    deque.offer(tmp.right);
                } else if (tmp.right != null && tmp.left == null) {
                    return false;
                } else if (tmp.left != null) {
                    isSecondStep = true;
                    deque.offer(tmp.left);
                }else{
                    isSecondStep = true; 
                }
            }else{
                if(tmp.left!=null||tmp.right!=null){
                    return false;
                }
            }
        }
        return isSecondStep;
    }

 二、前序遍历的非递归写法

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

 所有的深度优先遍历都需要借助栈结构进行非递归写法。

 不断地碰到根节点入栈以后,出栈,然后先将右子树入栈,再将左子树入栈中(保证左子树在右子树上方优先出栈),达到根左右的遍历目的。

首先排除树为空的情况,然后创建栈存储根节点。

 然后进入循环,循环的终止条件就是栈空,出栈取出根节点,当该节点的右子树不为空那么就入栈,然后再判断左子树是否为空,为空则直接忽略。

 然后继续出栈取出根节点,这时右子树为空那么久忽略,然后左子树非空,非将左子树入栈。

 然后再出栈,这时左右子树都为空则忽略,并且stack为空所以循环结束,返回list即可。

    public List<Integer> preorderTraversal(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        List<Integer> list = new ArrayList<>();
        Deque<TreeNode> stack  = new ArrayDeque<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.poll();
            list.add(node.val);
            if(node.right!=null){
                stack.push(node.right);
            }
            if(node.left!=null){
                stack.push(node.left);
            }
        }
        return list;
    }

三、中序遍历的非递归写法

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

 中序遍历是左跟右的顺序,所以需要先将向左碰到的节点压入栈中,直到碰到第一个左子树为空的结点这时就可以输出了。

所以首先排除树为空的情况,然后创建一个变量node使他等于树根,然后进入循环,若node!=null那么将他入栈,然后让node = node.left,向左搜索。

 这时node就等于空了。所以找到了最左的结点,保存并且出栈,然后去探索它的右节点。

 再次进入循环仍然一直向左探索,并且入栈。

 这时node就等于空了,保存并且出栈,继续探索其右节点,但是这时它的右节点是空的,所以循环的条件是node !=null ||!stack.isEmpty(),需要继续进入循环。

 这时node为空,所以直接出栈,然后探索出栈元素的右节点,但是这时右节点为空并且栈为空,所以循环结束。

    public List<Integer> inorderTraversal(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        List<Integer> list = new ArrayList<>();
        Deque<TreeNode> stack  = new ArrayDeque<>();
        TreeNode node = root;
        while (node !=null ||!stack.isEmpty()){
            while(node!=null){
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            list.add(node.val);
            node = node.right;
        }
        return list;
    }

四、后序遍历的非递归写法

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

后序遍历相对于前面两个遍历会更难一些,后续遍历是左右根的顺序,仍然需要左子树走到底,然后回到根节点,这时需要判断右子树不为空的情况下这个右子树有没有被我们访问到,所以引入prev遍历,prev表示上一个完全被处理过得结点(循环开始之前为空)当node.right==null || node.right!=prev时,以node为跟的右子树已经完全被处理就可以放心的弹出node,将它的val添加到list。

排除树为空之后进入循环和中序遍历一样将树向做走到头并且入栈。

 这时出栈并且存储为node,然后判断node.right==null||node.right!=prev,并不满足说明他的右子树不为空并且还没有被处理,所以将node再次入栈,然后访问右子树node = node.right。

 然后再次进入循环,还是先一直向左走。

 然后出栈并且存储为node,这时node.right为空,所以直接添加其val到list中,使prev = node并且使node = null。

 然后再进入循环,出栈并且存储为node,它的node.right仍为空,所以list.add(node.val);prev = node;node = null;

  然后再进入循环,出栈并且存储为node,它的node.right==prev,所以list.add(node.val);prev = node;node = null;到这儿栈为空并且node==null所以循环结束,返回list。

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root==null){
            return list;
        }
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode node = root;
        TreeNode prev = null;
        while (node!=null||!stack.isEmpty()){
            while (node!=null){
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            if(node.right==null||node.right==prev){
                list.add(node.val);
                prev = node;
                node = null;
            }else{
                stack.push(node);
                node = node.right;
            }
        }
        return list;
    }

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

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

相关文章

Vue脚手架

脚手架 安装步骤 全局安装vue/cli npm install -g vue/cli 安装之后使用不了vue的命令&#xff0c;查看nodejs文件发现我把vue装在了node_globalnpm这个文件夹中。 解决方法&#xff1a;新增一条path指向该文件夹 切换到你要创建的目录创建脚手架 vue create 项目名称 根据…

[附源码]Python计算机毕业设计Django保护濒危动物公益网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Hack The Box】linux练习-- Talkative

HTB 学习笔记 【Hack The Box】linux练习-- Talkative &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月27日&#x1f334; &#x…

初始数据结构

目录 1. 集合的框架 集合框架的重要性 数据结构的介绍 算法的介绍 容器背后对应的数据结构 2. 时间复杂度和空间复杂度 算法效率 时间复杂度 时间复杂度的概念 大O的渐进表示法 常见的时间复杂度的计算 空间复杂度 空间复杂度的概念 从本章开始又要开始新的篇章&a…

[附源码]Python计算机毕业设计Django班级事务管理论文2022

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

k8s上部署Harbor通过Nginx-Ingress域名访问

目录 1、k8s集群环境&#xff0c;通过kubesphere安装部署。 1.1 集群基本信息 1.2 集群节点信息 2、安装Harbor 2.1、使用Helm添加Harbor仓库 2.2 、通过openssl生成证书 2.3、 创建secret 2.4、 创建nfs存储目录 2.5、 创建pv 2.6、创建pvc 2.7、values.yaml配置文件 2.…

3-UI自动化-八大元素定位,xpath定位方式和相关的常问面试题

3-UI自动化-八大元素定位&#xff0c;xpath定位方式和相关的常问面试题八大元素定位八大元素定位的使用通过xpath定位xpath语法1. xpath逻辑运算定位2. 层级条件定位3. 索引定位4. 文本定位text()WebElement对象WebElement对象常用属性WebElement对象常用方法find_element()和 …

【Mybatis编程:插入和根据id删除相册数据】

目录 1. Mybatis编程&#xff1a;插入相册数据 2. Mybatis编程&#xff1a;根据id删除相册数据 1. Mybatis编程&#xff1a;插入相册数据 当某个数据表中的id被设计为“自动编号”的&#xff08;auto_increment&#xff09;&#xff0c;在配置<insert>标签时&#xff0…

开心公寓房屋出租管理系统的设计与实现(系统源码+技术文档+论文)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

基于51单片机病房呼叫系统(64位病床)

资料编号&#xff1a;189 下面是仿真演示&#xff1a; 189-基于51单片机病房呼叫系统&#xff08;64位病床&#xff09;&#xff08;仿真源程序原理图全套资料&#xff09;功能介绍&#xff1a; 设计一个可容64张床位的比那个房呼叫系统。 1、每个床位都有一个按钮&#xf…

InnoDB存储引擎简介

InnoDB存储引擎是一种兼顾高可靠性和高性能的通用存储引擎&#xff0c;在MySQL5.5之后&#xff0c;被选为MySQL的默认存储引擎 InnoDB的特点 1 DML操作循环ACID模型&#xff0c;支持事务 这里就印出了我们之前的知识点 DML操作就是我们对数据进行 增删除查改操作 ACID分别代表…

HTML小游戏14 —— H5横版冒险游戏《无限生机》(附完整源码)

&#x1f482; 网站推荐:【神级源码资源网】【摸鱼小游戏】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的计…

[ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(三)CSRF相关面试题

​ &#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成…

Azure CDN

Azure CDN Azure CDN 是服务器的分发网络&#xff0c;可以将网页内容更高效地分发给终端用户。 CDN在POP点的边缘服务器缓存内容&#xff0c;这样更临近终端用户&#xff0c;延迟低。 Azure CDN 给开发者提供全球解决方案&#xff0c;能够将内容放在全球各个节点&#xff0c;提…

MotoSimEG-VRC软件:龙门架外部设备添加以及示教编程与仿真运行

目录 概述 龙门架添加与属性配置 龙门架软限位设定 龙门架示教编程 仿真运行 概述 龙门架是工业生产中十分常见的自动化设备&#xff0c;由于其具备三维空间内的多自由度运动特性&#xff0c;通常被作为堆垛机&#xff0c;广泛应用在仓储物流领域。也可以作为直角坐标机器…

如何通过 Hardhat 来验证智能合约

在很大程度上&#xff0c;由于部署到通用区块链的智能合约的不变性&#xff0c;安全始终是用户和企业的首要任务。因此&#xff0c;在以太坊上开发智能合约的关键步骤之一是初始部署后的 Etherscan 验证。Etherscan 使任何人&#xff0c;从用户到经验丰富的开发人员和 bug hunt…

计算机组成原理课程设计(1)

指令设计 计算机组成原理课程设计 1、完成以下9条指令的设计&#xff1a; LDI Rd,#data&#xff0c;LDA Rd,adr&#xff0c;STA adr,Rs&#xff0c;LDR Rd,Rs&#xff0c;ADD Rd,Rs&#xff0c;XOR Rd,Rs&#xff0c;JMP adr&#xff0c;JZ adr&#xff0c;HALT 2.指令设计 …

全球著名漫画家蔡志忠创作的“EIS元宇宙之门”数字艺术品限量发售!11.29正式开售

开启宇宙之门 2022年12月3日&#xff0c;EIS我们将一起迎接一个新的爆发机会——品牌将正式接轨元宇宙一个全新的营销时代即将来临&#xff01;首次集结千位元宇宙领域品牌营销头号玩家&#xff0c;找到通往元宇宙智慧的不二法门&#xff01; 品牌营销领域一次全新的风向标&am…

SPARK数据分析

有了 DataFrame 之后&#xff0c;我们该如何在 DataFrame 之上做数据探索、数据分析&#xff0c;以及各式各样的数据转换呢&#xff1f;在数据处理完毕之后&#xff0c;我们又该如何做数据展示与数据持久化呢&#xff1f;今天这一讲&#xff0c;我们就来解答这些疑问。 为了给开…

[附源码]计算机毕业设计springboot创新创业管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…