[Java]前中后序遍历二叉树/递归与非递归

news2024/11/18 4:35:32

一、递归方法

首先,树形结构都是由递归方式定义的。那么递归是怎么用的?

1、终止条件;2、调用自身

分析

1、什么时候停止?

当结点值为空的时候,返回null;

2、如何调用自身?

以前序遍历为例:前序遍历的顺序是——根节点、左节点、右节点

先打印根节点,然后打印经过前序遍历的左子树,最后打印经过前序遍历的右子树

其他两种遍历方法同理

前序遍历

public void preOrder(TreeNode root){//前序遍历
        if (root == null){
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

中序遍历

public void inOrder(TreeNode root){//中序遍历
        if (root == null){
            return;
        }
        preOrder(root.left);
        System.out.print(root.val + " ");
        preOrder(root.right);
    }

 后序遍历

public void postOrder(TreeNode root){//后序遍历
        preOrder(root.left);
        preOrder(root.right);
        System.out.print(root.val + " ");
    }

二、非递归方法

分析

因为树形结构都是由递归方式定义的,所以非递归方法就是用其他方法来模拟递归。

我们要通过栈中的结点才能从其左节点遍历到右节点。

我这里使用的是栈,当然也可以使用其他结构

前序遍历

以深度为2的二叉树举例:

1、将根节点A入栈,打印A,cur指向cur.left

 2、将cur指向的结点cur入栈,并打印B。cur指向左节点,此时cur为空。

3、此时左节点已经遍历完毕,开始遍历右节点。弹出栈顶元素并设为top,使得cur等于top,cur移向右节点 。此时对于cur指向的B结点来说左子树为空,右子树也为空。说明B结点已经遍历完了。

 4、上一个栈顶元素已经左右子树遍历完了。此时再弹出栈顶元素,开始遍历其右子树。cur指向top

5、如果此时top的右边有结点,则将其入栈。

 6、cur指向其左边,查看是否有左子树。cur = cur.left

7、左侧为空则开始遍历其右子树。弹出栈顶元素,cur = top 。然后cur = cur.right

8、 发现右侧为空,且栈为空。遍历结束

代码如下

public void preOrderNor(TreeNode root){
        //模拟遍历的终止条件
        if (root == null){
            return;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack = new ArrayDeque<>();
        //如果指针cur不为空且栈中还有元素,说明遍历未结束
        while (cur != null || !stack.isEmpty()){
            //如果cur不为空,将其入栈(用以和其右子树产生联系)并打印,然后查看其左子树,
            //直到左子树为空
            while (cur != null){
                stack.push(cur);
                System.out.println(cur.val + " ");
                cur = cur.left;
            }
            //此时左子树为空,弹出栈顶元素开始遍历其右子树
            TreeNode top = stack.pop();
            cur = top.right;
        }
    }

中序遍历与后序遍历同理

中序遍历

public void inOrderNor(TreeNode root){
        if (root == null){
            return;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack = new ArrayDeque<>();
        while (cur != null || !stack.isEmpty()){
            while (cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.println(cur.val + " ");
            cur = top.right;
        }
    }

 后序遍历

public void postOrderNor(TreeNode root){
        if (root == null){
            return;
        }
        TreeNode cur = root;
        TreeNode prev = null;
        Deque<TreeNode> stack = new ArrayDeque<>();
        while (cur != null || !stack.isEmpty()){
            while (cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            //此时左子树已经遍历完了,但是还不能弹出栈顶元素。
            //因为这是后续遍历,根节点要在右结点打印后才能打印
            //现在弹出去后面就没法打印这个根节点了
            TreeNode top = stack.peek();
            if (top.right == null || top.right == prev){
                System.out.println(top.val + " ");
                stack.pop();
                prev = top;
            }else {
                cur = top.right;
            }
        }
        System.out.println();
    }

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

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

相关文章

应用案例|基于三维机器视觉的机器人引导电动汽车充电头自动插拔应用方案

Part.1 项目背景 人类对减少温室气体排放、提高能源效率以及减少对化石燃料的依赖&#xff0c;加速了电动汽车的普及&#xff0c;然而&#xff0c;电动汽车的充电依然面临一些挑战。传统的电动汽车充电通常需要人工干预&#xff0c;插入和拔出充电头&#xff0c;这不仅可能导致…

2.MySQL的调控按钮——启动选项和系统变量

2.MySQL的调控按钮——启动选项和系统变量 1.启动选项和配置文件1.1 在命令行上使用选项1.2 配置文件中使用选项1.2.1 配置文件路径1.2.2 配置文件的内容1.2.3 特定 MySQL 版本的专用选项组1.2.4 配置文件的优先级1.2.5 同一个配置文件中多个组的优先级1.2.6 defaults-file 的使…

【杂记】Ubuntu20.04装系统,安装CUDA等

装20.04系统 安装系统的过程中&#xff0c;ROG的B660G主板&#xff0c;即使不关掉Secure boot也是可以的&#xff0c;不会影响正常安装&#xff0c;我这边出现问题的主要原因是使用了Ventoy制作的系统安装盘&#xff0c;导致每次一选择使用U盘的UEFI启动&#xff0c;就会跳回到…

利用经典热门电视剧写爆款公众号爆文10万+阅读量

热门经典的影视综艺真的是微信公众号的流量宝地啊&#xff01; 比如《甄嬛传》、《知否知否应是绿肥红瘦》、《琅琊榜》&#xff0c;这些都是有着10万阅读量的高产区。 写这类剧评的人也非常多&#xff0c;需要有观点、有态度&#xff0c;才能抓住人的眼球。一般都是那些大号…

SpringMVC(四)域对象共享数据

pageContext:表示的是jsp页面的范围 HttpServletRequest:表示的是一次请求的范围 HttpSession:表示的是一次会话的范围 ServletContext:表示的是整个应用的范围 一、向请求域中共享数据&#xff1a; 1.1使用ServletAPI向request域对象共享数据 RequestMapping("test…

什么是Spring Web MVC

Spring Web MVC 概念 Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中。它的 正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc)&#xff0c;但它通常被称为"Spring MVC". 什么是Servlet Servlet 是…

时间复杂度(补充)和 空间复杂度

大家好啊&#xff0c;我今天来给大家分享有关空间复杂度的知识。感谢大家对我的支持&#xff0c;我会继续加油更新博客&#xff0c;努力提高博客质量的。 我们在这里先补充时间复杂度的一些实例&#xff1a; 补充实例1&#xff1a; // 计算BinarySearch的时间复杂度&#xff…

零资源的大语言模型幻觉预防

零资源的大语言模型幻觉预防 摘要1 引言2 相关工作2.1 幻觉检测和纠正方法2.2 幻觉检测数据集 3 方法论3.1 概念提取3.2 概念猜测3.2.1 概念解释3.2.2 概念推理 3.3 聚合3.3.1 概念频率分数3.3.2 加权聚合 4 实验5 总结 摘要 大语言模型&#xff08;LLMs&#xff09;在各个领域…

笔记:电子设备接地,接的到底是什么地?

电路中有“地”&#xff0c;设备中有“地”&#xff1b;都是“地”&#xff0c;此地非彼地。 混淆的原因 有些混淆&#xff0c;是以为中文翻译造成的&#xff0c;英文所有Ground都统一翻译为“地”&#xff1b; 例1&#xff1a;英文Circuit Ground&#xff0c;应该翻译为电路…

RedissonCach的源码流程

上&#xff1a; https://blog.csdn.net/Michelle_Zhong/article/details/126384566 中&#xff1a; https://blog.csdn.net/michelle_zhong/category_11874153.html 下&#xff1a; https://blog.csdn.net/Michelle_Zhong/article/details/126391915?ops_request_misc%257B%…

细说RTSP、RTMP和GB28181区别

好多流媒体初学者&#xff0c;对RTSP、RTMP和GB28181三者容易混淆&#xff0c;不了解他们的使用场景和区别&#xff0c;本文抛砖引玉&#xff0c;大概介绍下三者的区别。 RTSP&#xff08;Real-Time Streaming Protocol&#xff09;、RTMP&#xff08;Real-Time Messaging Pro…

实战|如何低成本训练一个可以超越 70B Llama2 的模型 Zephyr-7B

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。快来看看有哪些近期更新吧&#xff01;&#x1…

Flutter的The file name ‘xxxx.dart‘ isn‘t a snake_case identifier警告

文章目录 警告原因分析解决方法dart的一些命名规则变量和函数命名&#xff1a;类和类型命名&#xff1a;常量和枚举&#xff1a;文件命名&#xff1a;包命名&#xff1a;注释&#xff1a;命名一致性&#xff1a;避免缩写&#xff1a;可搜索的命名&#xff1a; 一些好习惯 警告 …

基于 51 的点阵屏显示·16*16 点阵仿真实验(静态显示,左移显示)

若想更详细了解可以先跳转到&#xff1a; 基于 51 的点阵屏显示 8*8 点阵仿真实验&#xff1a; 基于 51 的点阵屏显示 8*8 点阵仿真实验-CSDN博客 对一个模块进行了解 16*16 点阵的显示原理 虽然完成了上面 8*8 点阵的显示&#xff0c;但是由于点的数量太少以至于它的显示效果并…

简历自动生成工具

简历自动生成工具 简历自动生成工具&#xff0c;可根据提供的关键字生成完整内容&#xff0c;并应用于多个模板中。避免想更换简历风格的小伙伴&#xff0c;重复编辑简历的烦恼。 使用方法 每个求职者都需要认真对待自己的简历&#xff0c;特别是那些实力还不错的&#xff0c…

Centos如何安装Mysql

1、安装前检查是否存在mysql yum list installed mysql* ①如或显示了列表&#xff0c;说明系统中有MySQL **yum卸载 ** 根据列表上的名字&#xff08;[中括号为可选项]&#xff09; yum remove [填写列表显示出来的所有内容] rm -rf /var/lib/mysql rm /etc/my.cnf②rpm查…

【Linux】zip 命令使用

zip 命令用于压缩文件。压缩后的文件后缀名为 .zip。 语法 zip [参数] [文件] zip命令 -Linux手册页 命令选项及作用 执行令 zip --help 和 zip --help2 执行命令结果 参数 -A 调整可执行的自动解压缩文件。-b<工作目录> 指定暂时存放文件的目录。-c 替每个被压缩的…

LrC 13 ACR 16:镜头模糊

的Adobe Lightroom Classic 13 &#xff08; 2023 年 10 月版&#xff09;及 Adobe Camera Raw 16 新增的镜头模糊 Lens Blur功能可以基于 AI 技术生成深度图&#xff0c;并依据深度图对图像添加模糊和焦外成像&#xff08;散景光斑&#xff09;效果。 LrC&#xff1a;修改照片…

devCpp显示文件未编译

问题背景 刚刚去下载了devcpp&#xff0c;然后保存好代码之后点击编译运行出现文件未编译 问题细节 单独编译的时候显示这个当时没怎么注意 然后一直点编译运行死活显示文件未编译 目录下也没有exe文件 具体原因及代码 const int maxLine1e510; int arr[maxLine][maxLine]…

Windows VS C++工程:包含目录、库目录、附加依赖项、附加包含目录、附加库目录配置与静态库、动态库的调用——以OCCI的配置为例

文章目录 1 包含目录&#xff08;Include Directories&#xff09;/ 附加包含目录&#xff08;Additional Include Directories&#xff09;1.1 区别和作用1.2 设置路径 2 库目录&#xff08;Library Directories&#xff09;/ 附加库目录&#xff08;Additional Library Direc…