【数据结构】二叉树遍历的非递归实现

前言:

        本文使用栈以非递归的形式遍历整颗二叉树,我是通过数组模拟栈来实现的,如果对用数组模拟栈不太熟悉,你可以直接使用Stack类作为栈实现。

前序(先序)遍历:

        要求:二叉树节点的打印顺序为:中、左、右。

        思路:每次弹出一个节点就添加到结果集,如果节点的右孩子不为空,就让右孩子入栈、如果节点的左孩子不为空,就让左孩子进栈;栈会帮我们控制节点的弹出顺序。

        题目链接:144. 二叉树的前序遍历 - 力扣(LeetCode)

        Code:

class Solution {

    //题目规定节点个数在100以内
    public static int MAX = 101;
    public static TreeNode [] stack = new TreeNode[MAX];
    //栈中的元素个数
    public static int size;
    public List<Integer> preorderTraversal(TreeNode root) {
        //空树直接返回空集合
        if(root == null)
        return List.of();

        //一开始栈中没有元素
        size = 0;
        //头节点入栈
        stack[size++] = root;
        List<Integer> ans = new ArrayList<>();
        
        //只要栈不为空,一直弹出节点
        while(size > 0){
            TreeNode node = stack[--size];
            ans.add(node.val);
            
            //先让右孩子入栈、再让左孩子入栈
            //栈弹出节点时,左孩子先出栈、右孩子后出栈
            if(node.right != null)
            stack[size++] = node.right;

            if(node.left != null)
            stack[size++] = node.left;
        }
        return ans;
    }
}

              

中序遍历:

        要求:二叉树节点的打印顺序为:左、中、右。

        思路:指针p从根节点开始,不断向左子树遍历,遍历过程中将节点添加到栈中,当碰到空节点时,弹出此时处于栈顶的节点,将其添加到结果集中,并让指针p指向弹出节点的右节点,如果其右节点不为空,那么它会重复第一步的逻辑(不断向其左子树遍历),这样就能保证在处理完左树后,再去处理右树。

        题目链接:94. 二叉树的中序遍历 - 力扣(LeetCode)

        Code:

class Solution {

    public static int MAX = 101;

    public static TreeNode [] stack = new TreeNode[MAX];

    public static int size;
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root == null)
        return List.of();

        size = 0;
        List<Integer> ans = new ArrayList<>();
        TreeNode p = root;
        while(size > 0 || p != null){
            //只要指针p指向的节点不为null,就往其左子树遍历
            //并在遍历过程中,将节点添加到栈中
            if(p != null){
                stack[size++] = p;
                p = p.left;
            //当指针p指向的节点为null时,弹出栈顶节点
            //将栈顶节点添加到结果集
            //并让p指针指向栈顶节点的右子树
            }else{
                TreeNode node = stack[--size];
                ans.add(node.val);
                p = node.right;
            }
        }
        return ans;
    }
}

        图解:

        核心思想是:每次将左树处理完后,再去处理右树。

后序遍历:

        要求:二叉树节点的打印顺序为:左、右、中。

        思路:前序遍历通过先添加右节点、再添加左节点实现中、左、右的遍历顺序,那我们先让左节点入栈,再让右节点入栈不就可以实现中、右、左的遍历顺序吗?最后再另起一个栈,将前一个栈的结果装到新启的栈中,就实现了左、右、中的遍历顺序。

       题目链接:145. 二叉树的后序遍历 - 力扣(LeetCode)

        Code:

class Solution {
    public static int MAX = 101;
    
    //栈1
    public static TreeNode [] stack = new TreeNode[MAX];
    
    //栈2
    public static TreeNode [] collect = new TreeNode[MAX];
    
    //栈1的元素个数
    public static int size1;
    
    //栈2的元素个数
    public static int size2;
    public List<Integer> postorderTraversal(TreeNode root) {
        //空树返回空集合
        if(root == null)
        return List.of();
        
        //初始化两个栈的大小
        size1 = size2 = 0;
        
        //让头结点进入栈1
        stack[size1++] = root;
        //遍历栈1
        while(size1 > 0){
            //弹出栈1中的元素
            TreeNode node = stack[--size1];
            
            //放入栈2中
            collect[size2++] = node;
            
            //如果左节点不为空,就放入栈1
            if(node.left != null)
            stack[size1++] = node.left;
            
            //如果右节点不为空,就放入栈2
            if(node.right != null)
            stack[size1++] = node.right;
        }
        List<Integer> ans = new ArrayList<>();

        //遍历栈2,不断弹出栈2中的元素添加到结果集
        while(size2 > 0){
            TreeNode node = collect[--size2];
            ans.add(node.val);
        }        
        return ans;
    }
}

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

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

相关文章

山西电力市场日前价格预测【2023-12-04】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-04&#xff09;山西电力市场全天平均日前电价为179.48元/MWh。其中&#xff0c;最高日前电价为362.01元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

Leetcode1094. 拼车

Every day a Leetcode 题目来源&#xff1a;1094. 拼车 解法1&#xff1a;差分数组 对于本题&#xff0c;设 a[i] 表示车行驶到位置 i 时车上的人数。我们需要判断是否所有 a[i] 都不超过 capacity。 trips[i] 相当于把 a 中下标从 fromi 到 toi−1 的数都增加 numPassenge…

游戏配置表的导入使用

游戏配置表是游戏策划的标配&#xff0c;如下图&#xff1a; 那么程序怎么把把这张配置表导入使用&#xff1f; 1.首先&#xff0c;利用命令行把Excel格式的文件转化成Json格式&#xff1a; json-excel\json-excel json Tables\ Data\copy Data\CharacterDefine.txt ..\Cli…

Siemens-NXUG二次开发-Java开发环境配置[20231203]

Siemens-NXUG二次开发-Java开发环境配置[20231203] 1.NX/UG Java API官方开发文档2.安装Java83.安装jetbrain idea3.windows系统环境变量配置4.使用idea创建项目5.NXOpen Java代码生效流程6.API体系简述6.代码示例 1.NX/UG Java API官方开发文档 西门子NX/UG Java api开发文档…

一款自动帮你生成UI界面和代码的AI神器

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 只要描述你想要的UI是什么样的&#xff0c;它就能帮你生成&#xff0c;是不是很神奇&#xff1f; v0使用 AI 模型根据简单的文本提示生成用户界面和代码&#xff…

U盘不仅能在电脑上使用,在手机上也可使用,包括安卓和苹果手机,但苹果的较特殊

许多最好的安卓手机都使用USB-C端口在电脑上充电和来回传输文件,但如果你需要给老板发电子邮件的文件放在闪存驱动器或全尺寸SD卡上呢? 幸运的是,使用廉价的适配器电缆,你可以将USB加密狗或读卡器直接连接到手机上。你甚至可以直接使用USB-C闪存驱动器,以实现更轻松的过程…

Java基础之数组拷贝

Arrays.copyOf 详解 copyOf是Arrays类下面的一个方法,用于拷贝各种数组 以整型数组为例&#xff1a;int [ ] copyOf(int [ ]array,int newLength);第一个参数是想要拷贝到数组&#xff0c;第二个参数是新拷贝得到的数组的大小&#xff08;不一定非得和原始数组大小一样&…

深层神经网络(第四周)

这里省略了深层神经网络的前向传播和反向传播&#xff0c;内容和之前相似&#xff0c;不做过多描述。若今后需要&#xff0c;可以再补习。 一、为什么使用深层表示 解决问题时其实并不需要很大的神经网络&#xff0c;但是得有深度&#xff0c;得有比较多的隐藏层。这是为什么…

DBS note7 (end):DB Design

目录 一、前言 二、引言 三、Entity-Relationship Models&#xff08;实体-关系模型&#xff09; 1、关系约束 三、函数依赖和正则化 1、BCNF分解 2、无损分解 3、依赖关系保留分解 一、前言 略读过一遍CS186&#xff0c;对于CS186来说&#xff0c;绝对不止这 7 篇笔记…

SSM项目实战-登录验证成功并路由到首页面,Vue3+Vite+Axios+Element-Plus技术

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/sysUser.js import request from "../util/request.js";export const login (…

分布式锁框架Lock4j简单使用

最近项目中使用到了Lock4j的分布式锁组件&#xff0c;小编今天就带大家学习一下该框架&#xff0c;以及如何在我们项目中进行集成使用。 一、简介 Lock4j是一个分布式锁组件&#xff0c;它提供了多种不同的支持以满足不同性能和环境的需求&#xff1b;它基于Spring AOP&#…

SQL Server数据库数据文件的迁移

SQL Server数据库数据文件的迁移 如何将一台电脑中的SQL Server数据库数据文件迁移到另一台电脑上&#xff1f; 一、首先查看数据库文件保存在电脑中的位置&#xff1b; 如下图所示&#xff1a;右键-》属性-》数据库设置&#xff1b;可以找到数据库文件保存位置&#xff1b; …

【Node.js】Node.js环境下载与安装教程(Windows系统)

前言 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境&#xff0c;可以让你使用JavaScript进行服务器端编程。本教程将向你展示如何在Windows系统上下载和安装Node.js环境。 下载 首先&#xff0c;你需要下载Node.js环境。 打开Node.js官方网站&#xff1a;https://no…

Linux系列-1 Linux启动流程——init与systemd进程

背景&#xff1a; 最近对所有项目完成了一个切换&#xff0c;服务管理方式由&#xff1a; init-> systemd。对相关知识进行总结一下。 1.启动流程 服务器的整体启动流程如下图所示&#xff1a; POST&#xff1a; 计算机通电后进行POST( Power-On Self-Test )加电自检&am…

力扣每日一题day26[42. 接雨水]

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] …

MQ - KAFKA 基础篇

##1、KAFKA的核心组件/API Producer API&#xff0c;它允许应用程序向一个或多个 topics 上发送消息记录 Consumer API&#xff0c;允许应用程序订阅一个或多个 topics 并处理为其生成的记录流 Streams API&#xff0c;它允许应用程序作为流处理器&#xff0c;从一个或多个主…

github问题解决(持续更新中)

1、ssh: connect to host github.com port 22: Connection refused 从.ssh文件夹中新建文件名为config&#xff0c;内容为&#xff1a; Host github.com Hostname ssh.github.com Port 4432、解决 git 多用户提交切换问题 使用系统命令ssh创建rsa公私秘钥 C:\Users\fyp01&g…

使用Redis构建简易社交网站(1)-创建用户与动态界面

目的 本文目的&#xff1a;实现简易社交网站中创建新用户和创建新动态功能。&#xff08;完整代码附在文章末尾&#xff09; 相关知识 本文将教会你掌握&#xff1a;1.redis基本命令&#xff0c;2.python基本命令。 redis基本命令 hget&#xff1a;从哈希中获取指定域的值…

vitepress的使用

创建项目并启动项目 // 1.创建项目,直接在空项目下安装vitepress(npm/yarn等都可以,这个可以看官网,官网给了好几种安装方式) yarn add -D vitepress // 2.初始化配置项目(npm/官网也给了多种包管理工具的安装方式) npx vitepress init // 初始化命令执行完会遇到以下几个问题…

Python---函数递归---练习:猴子吃桃问题(本文以递归算法 解法为主)

相关链接&#xff1a;Python---函数递归---练习&#xff1a;斐波那契数列&#xff08;本文以递归算法为主&#xff09;-CSDN博客 案例&#xff1a;猴子吃桃问题 猴子吃桃问题。猴子第1天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾&#xff0c;又多吃了一个。…