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

一、递归方法

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

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.mzph.cn/news/121269.shtml

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

相关文章

php之 角色的权限管理(RBAC)详解

RBAC&#xff08;Role-based access control&#xff09;是一种常见的权限管理模型&#xff0c;通过将用户分配至特定的角色&#xff0c;以及为角色分配访问权限&#xff0c;实现了权限管理的目的。以下是关于RBAC的详细解释&#xff1a; 角色&#xff1a;RBAC模型的核心是角色…

Ubuntu编译 PCL 1.13.1 详细流程

Ubuntu编译 PCL 1.13. 详细流程 一、编译环境二、虚拟机准备1. 虚拟机扩容2. 配置交换分区 三、Cmake - gui 生成 MakeFile1. 解决 flann 依赖问题2. 配置 Cmake 四、编译安装1.编译&#xff1a;2. 安装 一、编译环境 Ubuntu&#xff1a;Ubuntu 20.04 VMware&#xff1a;VMwar…

如何学好C++?学习C和C++的技巧是什么?

如何学好C?学习C和C的技巧是什么&#xff1f; 你这三个问题&#xff0c;前两个都是意思是差不多的&#xff0c;那么怎么怎么学习C/C我来问答一下&#xff1a;最近很多小伙伴找我&#xff0c;说想要一些C资料&#xff0c;然后我根据自己从业十年经验&#xff0c;熬夜搞了几个通…

vue中父组件给子组件传递了参数后,什么时候确保子组件中收到的参数更新了

有这样的一个场景&#xff0c;在父组件中给子组件通过props进行了传值如students&#xff0c;然后想在父组件中调用子组件中的方法&#xff0c;这个方法中用到了父组件传递的参数&#xff0c;如何保证在父组件中调用子组件方法时这个值是最新的&#xff1f; 将父组件调用子组件…

技术的新浪潮:从SOCKS5代理到跨界电商的未来

在当今这个日新月异的技术时代&#xff0c;各种创新技术如雨后春笋般涌现。从SOCKS5代理到跨界电商&#xff0c;再到爬虫技术、出海战略和游戏产业的飞速发展&#xff0c;我们正处于一个技术变革的黄金时代。 SOCKS5代理&#xff1a;安全的网络通道 SOCKS5代理是一种网络协议…

Qt文件 I/O 操作

一.QFile 文件读取 QIODevice::ReadOnly QString filePath"/home/chenlang/RepUtils/1.txt"; QFile file(filePath); 1.逐行读取 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {QTextStream in(&file);while (!in.atEnd()) {QString line i…

go实现文件的读写

读文件 1.ioutil.ReadFile package mainimport ("fmt""io/ioutil" )func main() {filePath : "example.txt"data, err : ioutil.ReadFile(filePath)if err ! nil {fmt.Printf("无法读取文件&#xff1a;%v\n", err)return}fmt.Print…

【嵌入式开源库】timeslice的使用,完全解耦的时间片轮询框架构

完全解耦的时间片轮询框架构 简介项目代码timeslice.htimeslice.clist.hlist.c 创建工程移植代码实验函数说明timeslice_task_inittimeslice_task_addtimeslice_tak_deltimeslice_get_task_num 结尾 简介 timeslice是一个时间片轮询框架&#xff0c;他是一个完全解耦的时间片轮…

sift特征提取matlab

SIFT&#xff08;Scale-Invariant Feature Transform&#xff09;是一种用于图像处理和计算机视觉中的特征提取方法&#xff0c;它具有尺度不变性和旋转不变性等特点&#xff0c;通常用于图像匹配、物体识别和跟踪等任务。以下是如何在MATLAB中使用SIFT特征提取的一般步骤&…

Docker容器的应用部署

MySQL部署 案例需求&#xff1a; 在Docker容器中部署MySQL&#xff0c;并通过外部mysql客户端操作MySQL Server 实现步骤&#xff1a; 搜索mysql镜像拉取mysql镜像创建容器操作容器中的mysql 相关知识&#xff1a; 容器内的网络服务和外部机器不能直接通信外部机器和宿主…

三十七、【进阶】验证索引的效率

1、准备工作&#xff1a; 创建一张表&#xff0c;该表中有一千万条数据&#xff0c;名为tb_sku&#xff1b; 2、使用主键查询&#xff1a; select * from tb_stu where id1\G; 3、使用非索引查询&#xff1a; 4、给sn字段创建索引&#xff1a; 在创建过程中&#xff0c;发现…

如何使用 nvm-windows 这个工具来管理你电脑上的Node.js版本

nvm-windows 是一个用于管理在 Windows 上安装的多个 Node.js 版本的工具。以下是安装和使用 nvm-windows 的步骤&#xff1a; 第1步&#xff1a;下载 nvm-windows 访问 nvm-windows 的 GitHub发布页面.下载最新版本的 nvm-setup.zip 文件。 第2步&#xff1a;安装 nvm-wind…

JavaScript之while和do while循环的用法

JavaScript之while和do while循环的用法 1、while的用法2、do while的用法 1、while的用法 1&#xff09;while循环的基本语法&#xff1a; while (condition) { // code to be executed while the condition is true }当条件为真&#xff08;即condition的结果为true&…

conda虚拟环境笔记收录

1、安装conda 增加执行权限&#xff1a; chmod x Anaconda3-2023.03-1-Linux-x86_64.sh 开始执行&#xff1a;./Anaconda3-2023.03-1-Linux-x86_64.sh2、查看版本 conda --version3、查看当前虚拟环境 虚拟环境和全局环境有前缀可见 如果不进行设置&#xff0c;重新启动就变成…

C语言中的结构体和联合体有什么区别?

文章目录 1. 结构体(Structures)的理论知识详解1.1 C结构体语法1.2 结构体用法案例2. 联合体(Unions)的理论知识详解2.1 C联合体语法2.2 联合体数据大小2.3 C联合体用法案例3. 结构体和联合体的区别和联系3.1 结构体和联合体的区别3.2 结构体和联合体联系4. 实际代码在工作…

MySQL的基础(一)

MySQL的基础&#xff08;一&#xff09; SQLSQL的语法特点主要包括以下几点&#xff1a;一、 SQL - DDL -- 数据定义语言1.1 数据库操作1.1 显示现有的数据库1.2 创建数据库1.3 删除数据库1.4 使用 1.2 数据表操作1.2.1 表查询1.2.2 表创建1.2.3 修改表 1.2.4 小结 二、SQL - D…

【Python基础】Python基本数据类型 (新人必备)

Python是一种弱类型语言&#xff0c;因此变量的数据类型可以动态改变。Python基本的数据类型包括以下几种&#xff1a; 整型&#xff08;int&#xff09;&#xff1a;表示整数&#xff0c;如1、2、3等。浮点数&#xff08;float&#xff09;&#xff1a;表示带有小数部分的数字…

calcite 校验层总结

1、校验的作用 1&#xff09;完善语义信息 例如在SQL语句中&#xff0c;如果碰到select * 这样的指令&#xff0c;在SQL的语义当中&#xff0c;“*” 指的是取出对应数据源中所有字段的信息&#xff0c;因此就需要根据元数据信息来展开。 2&#xff09;结合元数据信息来纠偏…

XTU-OJ 1253-Robot

Robot 题目描述 有N个任务需要Robot去完成&#xff0c;这个N个任务的地点在一个数轴上&#xff0c;坐标为1到n。每个任务需要先完成ai个任务才能开始去做。Robot可以在直线上左右移动&#xff0c;初始位置位于任务1的地点&#xff0c;方向朝向数轴正方向。请问Robot最少转换多少…

特殊类设计[下] --- 单例模式

文章目录 5.只能创建一个对象的类5.1设计模式[2.5 万字详解&#xff1a;23 种设计模式](https://zhuanlan.zhihu.com/p/433152245)5.2单例模式1.饿汉模式1.懒汉模式 6.饿汉模式7.懒汉模式7.1饿汉模式优缺点:7.2懒汉模式1.线程安全问题2.单例对象的析构问题 8.整体代码9.C11后可…