数据结构|二叉树的三种遍历方式,你掌握了几种?

news2025/3/1 13:23:14

目录

1、遍历方式

2、前序遍历

3、中序遍历

1、遍历方式

学习二叉树的结构,最简单的方式就是遍历二叉树。遍历二叉树就是通过某条线路对二叉树的各个结点进行一次访问,访问的方法有三种分为前序遍历、中序遍历、后续遍历,层序遍历它们的遍历顺序如下所示:

  • 前序遍历:根节点=》根节点的左子树=》根节点的右子树
  • 中序遍历:根节点的左节点=》根节点=》根节点的右子树
  • 后续遍历:根节点的左节点=》根节点的右节点=》根节点

在二叉树的遍历中,遍历的开始是从头节点开始的遍历的结束也是从头节点结束的。


有一个二叉树,它有六个节点ABCDEF其值为123456。对应的结构为:

  • A为根节点时,A的左子树是D,A的右子树是E,A的值为1。
  • B为根节点时,B的左子树是D,B的右子树是E,B的值为2。
  • C为根节点时,C的左子树是null,C的右子树是F,C的值为3。
  • D为根节点时,D的左子树是null,F的右子树是null,的值为4。
  • E为根节点时,E的左子树是null,F的右子树是null,的值为5。
  • F为根节点时,F的左子树是null,F的右子树是null,的值为6。

本期博文所演练的遍历方式,均以上图中的二叉树进行展示。


2、前序遍历

前序遍历,我们在上方已经了解到了它的遍历顺序为:根节点=》根节点的左子树=》根节点的右子树。因此前序遍历上述的定义好的二叉树的顺序应为:ABDECF得到的值也应该为124536。具体实现方式看下方讲解:

第一步,获取根节点A。判断A节点是否有左子树。有则往下一个左子树遍历。没有则遍历右子树,右子树也没有则返回父节点。如果无父节点则程序结束!

此步骤往A的左子树进行遍历,首先获取A节点,发现A存在左子树,则往下遍历A的左子树节点。此时遍历到节点为:A、元素为:1。


第二步,来到B节点,获取B节点。判断B节点是否有左子树。有则往下一个左子树遍历。没有则遍历右子树,右子树也没有则返回父节点。如果无父节点则程序结束!

此步骤往B的左子树进行遍历,发现B存在左子树,则往下遍历B的左子树节点。此时遍历到的节点为AB、元素为:12。

 


第三步,来到D节点,获取D节点。然后判断D节点是否有左子树有则往下一个节点遍历。没有则遍历右子树,右子树也没有则返回父节点。

此时发现D没有左子树,遍历D的右子树发现右子树也没有,返回到B节点,并且往B节点的右子树进行遍历。 此时遍历到的节点为:ABD、元素为:124。


第四步,来到E节点,获取E节点。判断E是否有左子树。有则往下一个节点遍历。没有则遍历右子树,右子树也没有则返回父节点。

此时,发现E节点没有左右子树,则返回到B节点,B节点再返回到A节点,A节点再遍历到C节点,此时遍历到的节点为:ABDE、元素为:1245。


第五步,来到C节点,获取C节点。判断C是否有左子树。有则往下一个节点遍历。没有则遍历右子树,右子树也没有则返回父节点。

此时发现,C节点没有左子树,则访问C节点右子树F节点获取F节点的根节点。往F的左子树进行遍历,此时获取到的节点为:ABDEC,元素为:12453。


最后一步,来到F节点,获取F节点。F节点没有左右子树,返回F节点的父节点C节点,C节点再返回到C的父节点A节点。最后发现A没有父节点,程序结束。此时获取到的节点为:ABDECF,元素为:124536。


以上就是对前序遍历步骤的一个详细讲解,下面我们来看代码的实现: 

//MyBinaryTree.java文件下
public class MyBinaryTree {

    //静态内部类BinaryTree
    static class BinaryTree {
        public int val;
        public BinaryTree left;
        public BinaryTree right;

        public BinaryTree(int val) {
            this.val = val;
        }
    }

    //根节点
    public BinaryTree root;

    //创建一个二叉树
    public void initBinaryTree() {
        BinaryTree A = new BinaryTree(1);
        BinaryTree B = new BinaryTree(2);
        BinaryTree C = new BinaryTree(3);
        BinaryTree D = new BinaryTree(4);
        BinaryTree E = new BinaryTree(5);
        BinaryTree F = new BinaryTree(6);
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.right = F;
        root = A;
    }

    //前序遍历二叉树
    public void preOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的元素
        System.out.print(tree.val+" ");
        //节点的左子树
        preOrder(tree.left);
        //节点的右子树
        preOrder(tree.right);
    }
}

//Test.java文件下
public class Test {
    public static void main(String[] args) {
        MyBinaryTree myBinaryTree = new MyBinaryTree();
        myBinaryTree.initBinaryTree();
        myBinaryTree.preOrder(myBinaryTree.root);
    }
}

运行后输出:  

我们可以运行后的结果与上述演练的最终结果是一致的。通过程序我们也不难看出二叉树的遍历是一种递归思想,它的终止条件就是节点本身不为空。另外细心的朋友可以发现前序遍历得到的首结果就是这个二叉树的头节点,因为头节点是第一个被遍历的。 


3、中序遍历

中序遍历的顺序为:根节点的左节点=》根节点=》根节点的右节点。因此,中序遍历本期二叉树得到的根节点顺序为:DBEACF、根节点元素为:425136。

第一步,遍历A的左节点。如果A节点有左节点往A的左节点遍历,不存在则获取A节点,并往A节点的右节点遍历,如果右节点也为空则返回父节点。此时,遍历到了B节点。以下的每个节点也是同此步骤进行的。


第二步,遍历来到B节点。判断B节点的左节点不为空。遍历来到D节点,判断D节点的左子树为空,获取D节点,访问D的右子树为空返回父节点B,获取B节点的根节点。此时遍历到的节点为:DB,元素为:42。


第三步,遍历来到E节点。E节点的左子树为空,获取E节点,右子树也是空返回父节点B,B节点返回父节点A,获取A节点的根节点。此时遍历到的节点为:DBEA,元素为:4251。


第四步,遍历来到C节点。C节点的左子树为空,获取C节点,判断C节点的右子树不为空。遍历到F节点,此时遍历到的节点为:DBEAC,元素为:42513。


第五步,遍历来到F节点。F节点的左子树为空,获取F节点,F节点的右子树也为空返回父节点C,C节点返回父节点A,A节点没有父节点,程序结束。此时遍历到的节点为:DBEACF,元素为:425136。程序结束。


中序遍历,我们只需将上述代码中的preOrder方法中的访问节点的根节点位置稍微改动一下,其余代码不变。 

    
//中序遍历二叉树
public void inOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的左子树
        preOrder(tree.left);
        //节点的元素
        System.out.print(tree.val+" ");
        //节点的右子树
        preOrder(tree.right);
    }

 运行后输出:

通过上述结果,我们可以看到输出的结果与上方展示的结果是一致。细心的朋友可以发现,当我们中序遍历后头节点的左侧都是左子树,头节点的右侧都是右子树。在上方代码中1的左侧为425,1的右侧为36,正好与我们的二叉树一致。因此,当我们知道了一个二叉树的头节点是谁后可以通过中序遍历推出这个二叉树的左、右则的树。 


4、后序遍历

后序遍历的步骤为:根节点的左节点=》根节点的右节点=》根节点,在本篇示例二叉树中对应的遍历节点顺序为:DEBFCA,节点元素为452631。

在上文中,前序遍历与后序遍历我给大家展示了流程图以及实现步骤,其实后序遍历也是一样的按照左节点、右节点、根节点的遍历顺序去遍历,在此博主就不多讲解了,大家可以自己尝试去画图。

后序遍历二叉树的代码,我们也是将preOrder方法中的根节点位置互换一下即可:

//后序遍历二叉树    
public void postOrder(BinaryTree tree) {
        if( tree == null) {
            return;
        }
        //节点的左子树
        preOrder(tree.left);
        //节点的右子树
        preOrder(tree.right);
        //节点的元素
        System.out.print(tree.val+" ");
    }

运行后输出:

通过运行结果可以看到与上方遍历得到的结果是一致的。通过观察,我们也可以知道。知道了一个二叉树的后序遍历,就能得到头节点,因为后序遍历的最后一个数据就是我们的头节点。


当我们知道一个二叉树的前序遍历或后续遍历结果与中序遍历结果时,就能轻易的推出这个二叉树的全貌。

如一个二叉树的前序遍历结果为:ABDECF,中序遍历结果为:DBEACF。则这个二叉树的头节点为:A,左侧子树为:DBE、右侧子树为CF。因此可以推出这个二叉树的全貌为:

当然,知道一个二叉树的中序遍历与后序遍历也能很轻松的推出这个二叉树,但知道前序遍历和后序遍历却不能推出这个二叉树,因为通过这两个遍历方式我们不能得到左侧、右侧的子树是什么。


本期博客到这里就结束了,大家下来了可以自己去画图理解不懂之处或者私信博主、评论留言都可以。感谢你的阅读,我们下期再见!

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

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

相关文章

TryHackMe-Year of the Fox(Linux渗透测试)

Year of the Fox 你能熬过狡猾的狐狸吗? 端口扫描 循例nmap 有个域名,加入hosts SMB枚举 smbmap enum4linux -a,枚举到两个账户 Web枚举 进80发现需要登录 上hydra RCE to Getshell 进来可以查看一些文件 bp发现这里存在过滤 burpfuzz一…

数据结构---作业1时间复杂度

本专栏是对自我的平时作业错题及掌握知识不牢固的地方的总结专栏. 1.大O是一个渐进表示法,不会去表示精确的次数,cpu的运算速度很快,估计精确的没有意义。 2. 此函数有一个循环,但是循环没有被执行n次,i每次都是2倍进…

再不转型为ChatGPT程序员,有遭受降维打击的危险

Open AI在演示GPT-4的时候,有这么一个场景:给一个界面草图,就可以生成网页代码。这个演示非常简单,如果界面原型比较复杂呢?像这样:ChatGPT能不能直接生成HTML, CSS,JavaScript代码,把这个网页给…

【MySQL】表的约束

前言 hi~大家好呀,欢迎来到我的MySQL学习笔记系列~ 继上次数据类型的描述,这篇笔记重点记录DDL-数据定义语言对表的结构中的其他约束条件进行说明,以便让关系型数据库真正的保持完整性。 我的上一篇MySQL笔记~ 【MySQL】表的操作和数据类型_柒…

OpenCV实战之人脸美颜美型(七)——美颜demo

前言 之前我们已经完成了人脸检测、肤色检测、磨皮、美白功能,这一篇文章中我们将尝试利用OpenCV中的滑动条对象,结合窗口制作一个简单的demo。demo中会将上述功能集成进来,并通过滑动条来调整美白、磨皮力度观察其效果,先放一张效果图如下。 滑动条 OpenCV中可通过crea…

【Fluent】Run can not be started until validation issues are resolved.

一、问题背景 因为在fluent中用Discard Data, Replace Mesh选项替换了网格,但是没有抛弃算例设置等参数。 当时我以为网格是完全一样的,便忽略了产生冲突/错误的可能。 之后在calculate的时候,报错:Run can not be started unt…

联盟链是虚构的?没有用的?用FISCO BCOS来展示链委员这件事

前言 当前区块链大都使用的是投票决定这种方法,但是如何使现实中的投票转换到区块链中,如何让举手表决变得更加智能,如何让投票透明、安全、权威,这是区块链的一大设计思路,有很多人觉得联盟链是个梦,是个虚…

分享一个国内可用的免费ChatGPT网站

背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具,近期的热度直接沸腾🌋。 作为一个程序员,我也忍不住做了一个基于ChatGPT的网站,免费!免登陆!!国内可直接对话ChatGPT,也…

十年磨一剑,你要的低代码平台在这里

目录低代码平台现状没有创新的“拼凑”,没有好东西ivx平台是什么ivx与其他平台的区别产品思路不同用户不同学习价值不同应用范围不同有无框架限制总结低代码开发平台已成为企业数字化转型和应用程序开发的重要工具。它们提供了一种快速创建和部署应用程序的方法&…

【MySQL】DDL数据库、表的创建与管理

一、基本概念 1、从系统架构的层面来看,数据库从大到小依次是数据库服务器(上面安装了DBMS和数据库)、数据库(也称database或者schema)、数据表、数据表的行与列 二、创建和管理数据库 1、创建数据库 直接创建:CREATE DATABASE 数据库名;(使用默认的…

这篇文章价值很大:股票历史分时成交数据怎么简单获取?【干货】

文章目录前言一、准备二、使用步骤1.引入库2,使用这个API查询历史分时数据:3.查询完整历史分时数据4.其他查询方法参数格式:[(市场代码, 股票代码), ...]参数:市场代码, 股票代码, 文件名, 起始位置, 数量参数:市场代码…

【MySQL】(3)约束

文章目录表的约束空属性默认值列描述zerofill主键概念使用 alter 添加和删除主键联合主键如何设计主键自增长唯一键外键表的约束 所谓约束,就是不让你做某事,约束的存在,有助于程序员和用户合法合理地使用数据库。 数据类型其实就是对字段的…

【C++】位图的概念

文章目录位图的引入什么是位图位图的应用bitset的使用定义方式成员函数bitset的运算符重载>> 及 << 运算符赋值,关系,复合赋值,单目运算符[]重载位图的引入 无序的40亿个不重复的无符号整数,给一个无符号整数,如何判断一个数是否在这40亿个数中【腾讯面试题】 方法…

记一次浏览器下载错误处理-失败网络错误

背景 最近在自己电脑上Chrome浏览器正常使用&#xff0c;但只要是下载软件&#xff0c;就会在下载几十秒后&#xff0c;自动停止&#xff0c;报失败-网络错误&#xff0c;导致文件都下载不成功&#xff0c;如下图。 猜测是更改了哪块的配置&#xff0c;导致一直中断&#xff0…

28岁,终于从字节退休了...

大厂一直是每个程序员都向往职业目标&#xff0c;大厂意味着薪资高、福利好、倍有面儿&#xff0c;而且发展空间也大。甚至有人调侃不想进大厂的程序员不是好程序员。 而在网上&#xff0c;也有各个网友分享自己在大厂的经历&#xff0c;在某平台还有一个近2600万浏览的话题&a…

JavaEE——了解Spring,容器,Ioc,DI相关概念

目录 一、Spring 是什么 二、什么是容器 三、什么是loC 1. 什么是 IoC 2. 传统程序开发和控制反转式程序开发 (1). 传统程序开发 (2). 控制反转式程序开发 (3). 对比 3. Spring的功能 4. 将对象存放到容器中的好处 四、DI概念说明 IoC和DI的联系和区别&#xff1f;…

算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和

基础知识 什么是贪心&#xff1a;贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 但是贪心没有套路&#xff0c;做题的时候&#xff0c;只要想清楚 局部最优 是什么&#xff0c;如果推导出全局最优&#xff0c;其实就够了。 455.分发饼干 很容易想到&am…

Emlog底部显示当前在线人数

第一步&#xff1a;在模板文件里面创建“visitor.php”的文件吧下面代码入进去 code <?php//首先你要有读写文件的权限&#xff0c;首次访问肯不显示&#xff0c;正常情况刷新即可$online_log "slzxrs.dat"; //保存人数的文件到根目录,$timeout 30;//30秒内没…

计算机视觉__基本图像操作(显示、读取、保存)

计算机视觉__基本图像操作&#xff08;显示、读取、保存&#xff09; 本文目录&#xff1a; ✨ 一、前言 ✨ 二、图像显示&#xff08;使用OpenCV和Matplotlib显示图像&#xff09; &#xff08;1&#xff09;、使用OpenCV显示图像 &#xff08;2&#xff09;、使用Matplotl…

密集场景下的行人跟踪替代算法,头部跟踪算法 | CVPR 2021

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky LiEmail : 3435673055qq.com Time of completion&#xff1a;2023.4.8 Last edited: 2023.4.8 目录 摘要 主要内容 结果 这篇文章是CVPR 2021 的最新论文&#xff0c;文章的标题&#xff1a; 文章的主要内…