JAVA-二叉树的四种遍历

目录

一、二叉树的存储

二、二叉树遍历的概念

1.前序遍历

2.中序遍历 

3.后序遍历

4.层序遍历

三、概念面试题

四、代码实现

         1.前序遍历

2.中序遍历

3.后序遍历

4.层序遍历

五、其他写法(非递归)

1.非递归前序遍历

2.非递归中序遍历

3.非递归后续遍历


一、二叉树的存储

二叉树的存储结构 分为: 顺序存储 类似于链表的链式存储
本节主要讲解链式存储,顺序存储将会在写在堆博客篇。
二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式 ,具体如下:
// 孩子表示法
class Node {int val; // 数据域Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
}// 孩子双亲表示法
class Node {int val; // 数据域Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树Node parent; // 当前节点的根节点
}

本文采用孩子表示法来构建二叉树。 

二、二叉树遍历的概念

        学习二叉树结构,最简单的方式就是遍历。所谓遍历 (Traversal) 是指沿着某条搜索路线,依次对树中每个结 点均做一次且仅做一次访问 访问结点所做的操作依赖于具体的应用问题 ( 比如:打印节点内容、节点内容加 1) 。 遍历是二叉树上最重要的操作之一,是二叉树上进行其它运算之基础。

前序遍历: 根  左  右

中序遍历: 左  根  右

后续遍历: 左  右  根

根就代表对当前节点进行的一系列操作,那么根据规律发现,遍历方法名的叫法其实是根据对根的操作次序取的

1.前序遍历

前序遍历:进入当前节点,就对当前节点进行操作-》再进入左子树-》左子树操作完进入右子树后回到当前节点。循环往复

2.中序遍历 

中序遍历:进入当前节点,直接去访问右子树-》右子树归回来了再对当前节点进行操作-》再进入右子树后返回当前节点。循环往复

 3.后序遍历

后续遍历:进行当前结点,直接访问左子树-》归后返回右子树-》最后对当前结点进行操作

 4.层序遍历

这个就是从左往右,从上往下,符合我们人类的习惯

三、概念面试题

1. 某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为 ()
A: ABDHECFG         B: ABCDEFGH         C: HDBEAFCG         D: HDEBFGCA
完全二叉树: 层序遍历从左到右,从上到下。依次存储的中间不能有一个空子树。
那么这颗树就是这样的:

选A

2. 二叉树的先序遍历和中序遍历如下:先序遍历: EFHIGJK; 中序遍历: HFIEJKG. 则二叉树根结点为 ()
A: E         B: F         C: G         D: H
这里也给大家说一点关于前中后序的规律,怎么做这种题。
前序遍历的第一个就是根节点,后续遍历的最后一个就是根节点。
可以通过他们在中序遍历确定,左右子树。
选:A
提升难度:根据已知条件去构建这颗二叉树:
3. 设一课二叉树的中序遍历序列: badce ,后序遍历序列: bdeca ,则二叉树前序遍历序列为 ()
A: adbce         B: decab         C: debac         D: abcde

 选:D

4. 某二叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出 ( 同一层从左到右 ) 的序列为 ()
A: FEDCBA         B: CBAFED         C: DEFCBA         D: ABCDEF
同理一样,选A

四、代码实现

首先有一个二叉树的类

public class binaryTree {static class TreeNode {public char val;public TreeNode left;public TreeNode right;public TreeNode(char val) {this.val = val;}}public TreeNode createTree() {TreeNode A = new TreeNode('A');TreeNode B = new TreeNode('B');TreeNode C = new TreeNode('C');TreeNode D = new TreeNode('D');TreeNode E = new TreeNode('E');TreeNode F = new TreeNode('F');TreeNode G = new TreeNode('G');TreeNode H = new TreeNode('H');A.left = B;A.right = C;B.left = D;B.right = E;E.right = H;C.left = F;C.right = G;return A;}
}

通过createTree创建了这样一颗二叉树: 

1.前序遍历

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

对就是这么简单,那么我们分析一次:

运行结果:   刚好是和分析的一样

 

所以说二叉树是递归创建的

2.中序遍历

有了前序遍历的知识中序还不简单~

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

运行结果:

3.后序遍历

 // 后序遍历打印void postOrder(TreeNode root) {if(root == null) {return;}postOrder(root.left);postOrder(root.right);System.out.print(root.val + " ");}

运行结果:

4.层序遍历

这次我们用非递归的形式遍历,思路如下:

 那么可以发现第二步和第三步可以构成循环,直到队列最后为null了那么也就遍历完了

//二叉树的层序遍历public void levelOrder(TreeNode root) {if(root == null) {return;}Queue<TreeNode> queue = new LinkedList<>();//将root放入队列中queue.offer(root);//只要队列不为null,就循环while (!queue.isEmpty()) {//弹出队首元素,并打印TreeNode cur = queue.poll();System.out.print(cur.val + " ");//左右不为null就放入队列中,这个放入的顺序就决定了是层序打印if(cur.left != null) {queue.offer(cur.left);}if(cur.right != null) {queue.offer(cur.right);}}System.out.println();}

运行结果:

上述的遍历方法是比较推荐的,前中后就是递归形式所以最好用,层序不是递归最好用循环

但是还有非递归的前中后可以写。那么在这里讲一下

五、其他写法(非递归)

1.非递归前序遍历

    //前序遍历非递归写法public void preOrderNot(TreeNode root) {//利用栈的后进先出的原理,来实现if(root == null) {return;}Stack<TreeNode> stack =  new Stack<>();TreeNode cur = root;//最终遍历完的条件while (cur != null || !stack.isEmpty()) {//左子树遍历while(cur != null) {stack.push(cur);System.out.print(cur.val + " ");cur = cur.left;}//右子树遍历TreeNode top = stack.pop();cur = top.right;}}

运行结果:

2.非递归中序遍历

这个根之前差不多就不多说了

 //中序遍历非递归写法void inOrderNot(TreeNode root) {//利用栈的后进先出的原理,来实现if(root == null) {return;}Stack<TreeNode> stack =  new Stack<>();TreeNode cur = root;//最终遍历完的表现while (cur != null || !stack.isEmpty()) {//左子树遍历while(cur != null) {stack.push(cur);cur = cur.left;}//右子树遍历TreeNode top = stack.pop();//此时走完了这个结点的左子数System.out.print(top.val + " ");cur = top.right;}}

运行结果:

3.非递归后续遍历

//后续遍历的非递归写法void postOrderNot(TreeNode root) {//利用栈的后进先出的原理,来实现if(root == null) {return;}Stack<TreeNode> stack =  new Stack<>();TreeNode cur = root;TreeNode prev = null;//最终遍历完的表现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) {stack.pop();System.out.print(top.val + " ");//记录上一个被打印的结点,防止死循环prev = top;}else {cur = top.right;}}}

运行结果:

因为层序遍历用递归写,感觉没有什么应用的暂时不写了,如果后面发现有用作者再来补

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

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

相关文章

Spring FactoryBean到仿照mybatis @Mapper的实现

目录 FactoryBean原理FactoryBean例子org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean mybatis mapper bean的手动实现思考复习下Jdbc传统sql查询做法Mapper接口实现思路复习批量注册beanDefinition: ConfigurationClassPostProcessor自定义实现Mapp…

【Go】Go数据类型详解—数组与切片

1. 前言 今天需要学习的是Go语言当中的数组与切片数据类型。很多编程语言当中都有数组这样的数据类型&#xff0c;Go当中的切片类型本质上也是对 数组的引用。但是在了解如何定义使用数组与切片之前&#xff0c;我们需要思考为什么要引入数组这样的数据结构。 1.1 为什么需要…

flutter Get GetMiddleware 中间件不起作用问题

当使用 get: ^5.0.0-release-candidate-9.2.1最新版本时&#xff0c;中间件GetMiddleware各种教程都是让我们在redirect中实现&#xff0c;比如&#xff1a; overrideRouteSettings? redirect(String? route) {return RouteSettings(name: "/companyAuthIndexPage"…

【Idea启动项目报错NegativeArraySizeException】

项目场景&#xff1a; Idea启动项目报错&#xff08;打包不报错&#xff09;&#xff0c;项目在服务器部署运行没有问题&#xff0c;尝试了重启idea、重启电脑、maven clean/install 都不行 maven-resources-production:sample: java.lang.NegativeArraySizeException: -5833…

微信小程序:播放音频

在小程序开发中&#xff0c;音频播放是一个重要的功能。本文将详细介绍小程序音频播放的相关知识点&#xff0c;帮助开发者更好地掌握小程序音频播放的实现方法。 一、小程序音频播放的基本流程 在小程序中&#xff0c;音频播放的基本流程如下&#xff1a; 获取音频数据&#…

运行fastGPT 第四步 配置ONE API 添加模型

上次已经装好了所有的依赖和程序。 下面在网页中配置One API &#xff0c;这个是大模型的接口。配置好了之后&#xff0c;就可以配置fastGPT了。 打开 OneAPI 页面 添加模型 这里要添加具体的付费模型的API接口填进来。 可以通过ip:3001访问OneAPI后台&#xff0c;**默认账号…

RocketMQ 学习笔记01

一、MQ简介 1. 什么是MQ&#xff1f; MQ&#xff08;Message Queue&#xff0c;消息队列&#xff09; 是一种在分布式系统中用于实现进程间通信和数据传输的中间件。它通过在不同进程或应用程序之间传递消息&#xff0c;实现数据的异步处理、解耦和削峰填谷等功能。MQ广泛应用…

梁山派入门指南3——串口使用详解,包括串口发送数据、重定向、中断接收不定长数据、DMA+串口接收不定长数据,以及对应的bsp文件和使用示例

梁山派入门指南3——串口使用详解&#xff0c;包括串口发送数据、重定向、中断接收不定长数据、DMA串口接收不定长数据&#xff0c;以及对应的bsp文件和使用示例 1. 串口发送数据1.1 串口简介1.2 梁山派上的串口开发1.3 bsp_uart文件&#xff08;只发送不接收&#xff0c;兼容串…

Linux和Docker常用终端命令:保姆级图文详解

文章目录 前言1、Docker 常用命令1.1、镜像管理1.2、容器管理1.3、网络管理1.4、数据卷管理1.5、监控和性能管理 2、Linux 常用命令分类2.1、文件和目录管理2.2、用户管理2.3、系统监控和性能2.4、软件包管理2.5、网络管理 前言 亲爱的家人们&#xff0c;创作很不容易&#xf…

智能科技与共情能力加持,哈曼重新定义驾乘体验

2025年1月6日&#xff0c;拉斯维加斯&#xff0c;2025年国际消费电子展——想象一下&#xff0c;当您步入一辆汽车&#xff0c;它不仅能响应您的指令&#xff0c;更能理解您的需求、适应您的偏好&#xff0c;并为您创造一个独特且专属的交互环境。作为汽车科技领域的知名企业和…

关于2025年智能化招聘管理系统平台发展趋势

2025年&#xff0c;招聘管理领域正站在变革的十字路口&#xff0c;全新的技术浪潮与不断变化的职场生态相互碰撞&#xff0c;促使招聘管理系统成为重塑企业人才战略的关键力量。智能化招聘管理系统平台在这一背景下迅速崛起&#xff0c;其发展趋势不仅影响企业的招聘效率与质量…

机器视觉5-全连接神经网络

机器视觉5-全连接神经网络1 图像表示多层感知器全连接神经网络一、两层全连接网络表达式二、三层全连接网络表达式三、关于非线性操作的说明四、全连接神经网络的映射原理 全连接神经网络的权值一、线性分类器二、两层全连接网络三、总结 全连接神经网络线性不可分全连接神经网…

解锁转型密码:不同方向的技能与素质修炼手册

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 解锁…

ChatGPT提示词合集(国内大模型可参考使用)

行为迅速的Linux终端我想让你充当 linux 终端。我将输入命令&#xff0c;您将回复终端应显示的内容。我希望您只在一个唯一的代码块内回复终端输出&#xff0c;而不是其他任何内容。不要写解释。除非我指示您这样做&#xff0c;否则不要键入命令。当我需要用英语告诉你一些事情…

第三十八章 Spring之假如让你来写MVC——适配器篇

Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…

深度剖析RabbitMQ:从基础组件到管理页面详解

文章目录 一、简介二、Overview2.1 Overview->Totals2.2 Overview->Nodesbroker的属性2.3 Overview->Churn statistics2.4 Overview->Ports and contexts2.5 Overview->Export definitions2.6 Overview->Import definitions 三、Connections连接的属性 四、C…

使用 Python 编写一个简单的聊天机器人

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

Unity 自定义批量打包工具

打包配置项 using UnityEngine; using System.Collections.Generic;namespace MYTOOL.Build {[System.Flags]public enum VersionOptions{None 0,Major 1,Minor 4,Build 8,Revision 0x10,}/// <summary>/// 批量打包配置文件/// </summary>[CreateAssetMenu]…

JAVA实现五子棋小游戏(附源码)

文章目录 一、设计来源捡金币闯关小游戏讲解1.1 主界面1.2 黑棋胜利界面1.3 白棋胜利界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载更多优质源码分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/145161039 JA…

Flink概述

一、Flink是什么 二、Flink特点 三、Flink vs SparkStreaming 表 Flink 和 Streaming对比 Flink Streaming 计算模型 流计算 微批处理 时间语义 事件时间、处理时间 处理时间 窗口 多、灵活 少、不灵活&#xff08;窗口必须是批次的整数倍&#xff09; 状态 有 …