【数据结构】二叉树的层序遍历、前序遍历,中序遍历、后续遍历

目录

  • 一、前言
  • 二、二叉树的遍历概念
  • 三、根据遍历结果去推其他的遍历结果
    • 1.根据前序遍历、中序遍历,求后序遍历
    • 2. 已知中序和后序遍历,求前序遍历
  • 四、代码实现

一、前言

最近也是在准备笔试,由于没有系统的学过数据结构,所以花了半天的时间来学了下二叉树。现在记下来,以便后序查阅。

二、二叉树的遍历概念

二叉树的遍历是指从根结点触发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。

1). 前(先)序遍历

前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子书。

特点:

  1. 根—–>左——->右
  2. 根据前序遍历的结果可知第一个访问的必定是root结点

(2). 中序遍历

中序遍历:若二叉树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后访问根结点,最后中序遍历右子树。

特点:

  1. 左—–>根——->右
  2. 根据中序遍历的结果,再结合前序遍历的root结点去划分root结点的左右子树。

(3). 后序遍历

后序遍历:若二叉树为空,则空操作返回,否则从左到右先叶子结点后结点的方式遍历访问左右子树,最后访问根结点。

特点:

  1. 左——>右——>根
  2. 根据后序遍历的结果可知最后访问的必定是root结点。

(4). 层序遍历

层序遍历:若二叉树为空,则空返回,否则从树的第一层,即根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。

特点:

  1. 从左到右,从上到下
  2. 可知第一个访问的必定是root结点

例如

假如有如下的二叉树:

在这里插入图片描述

根据上面的定义,得出如下的遍历结果

前序遍历:ABDHIEJCFKG

中序遍历:HDIBEJAFKCG

后序遍历:HIDJEBKFGCA

层序遍历:ABCDEFGHIJK

我个人根据二叉树图来求遍历结果的经验是:先根据定义,给出所有子树的相对位置,然后再整理。

通过遍历循序确定根的位置,即前序(根在前)、中序(根在中间)、后序(根在最后)

三、根据遍历结果去推其他的遍历结果

相信这种情况下,考题的最多,一是考查如何递归倒推;二是节约试卷版面,画图也麻烦。

1.根据前序遍历、中序遍历,求后序遍历

例:

前序遍历: GDAFEMHZ

中序遍历: ADEFGHMZ

画树求法:

第一步,根据前序遍历的特点,我们知道根结点为G

第二步,观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。

第三步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。

第四步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。

第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。

该步递归的过程可以简洁表达如下:

  1. 确定根,确定左子树,确定右子树。
  2. 在左子树中递归。
  3. 在右子树中递归。
  4. 打印当前根。

那么,我们可以画出这个二叉树的形状:

在这里插入图片描述
那么,根据后序的遍历规则,我们可以知道,后序遍历顺序为:AEFDHZMG

2. 已知中序和后序遍历,求前序遍历

依然是上面的题,这次我们只给出中序和后序遍历:

中序遍历: ADEFGHMZ

后序遍历: AEFDHZMG

画树求法:

第一步,根据后序遍历的特点,我们知道后序遍历最后一个结点即为根结点,即根结点为G

第二步,观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树G右侧的HMZ必然是root的右子树

第三步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。

第四步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前后序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。

第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:

  1. 确定根,确定左子树,确定右子树。
  2. 在左子树中递归。
  3. 在右子树中递归。
  4. 打印当前根。

这样,我们就可以画出二叉树的形状,如上图所示,这里就不再赘述。

那么,前序遍历: GDAFEMHZ

关于二叉树,多练习几次就熟悉了。

四、代码实现

地址:GitHub

import java.util.LinkedList;
import java.util.Queue;

/**
 * 二叉树的前序、中序、后序、层序遍历
 *
 * @author hanson
 * @date 2024/3/13 13:56
 */
public class Traversal {

    // 定义树结构
    static class TreeNode {
        String val;
        TreeNode left;
        TreeNode right;

        public TreeNode(String val) {
            this.val = val;
            this.left = null;
            this.right = null;
        }
    }

    // 前序遍历 根左右
    public static void preorderTraversal(TreeNode root) {
        if (root != null){
            System.out.println(root.val + " ");
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
    }

    // 中序遍历 左根右
    public static void inorderTraversal(TreeNode root) {
        if (root != null){
            inorderTraversal(root.left);
            System.out.println(root.val + " ");
            inorderTraversal(root.right);
        }
    }

    // 后序遍历 左右根
    public static void postorderTraversal(TreeNode root) {
        if (root != null){
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            System.out.println(root.val + " ");
        }
    }

    // 层序遍历
    public static void levelOrderTraversal(TreeNode root){
        if (root == null) return;

        // 我们使用队列来辅助进行二叉树的层序遍历。队列的基本操作有 offer 和 poll:
        //
        //offer(E e) 方法用于将指定的元素插入到队列中,如果队列满了则返回 false。
        //poll() 方法用于从队列中取出并删除头部元素,如果队列为空则返回 null。
        //在二叉树的层序遍历中,我们首先将根节点入队,然后在循环中不断出队并访问节点,同时将其左右子节点入队,直到队列为空为止。这样可以保证按照层次遍历每个节点。
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        while (!queue.isEmpty()){
            TreeNode node = queue.poll();
            System.out.println(node.val + " ");

            if (node.left != null){
                queue.offer(node.left);
            }

            if (node.right != null){
                queue.offer(node.right);
            }
        }
    }

    public static void main(String[] args) {
        // 构造一个二叉树
        TreeNode root = new TreeNode("A");
        root.left = new TreeNode("B");
        root.right = new TreeNode("C");
        root.left.left = new TreeNode("D");
        root.left.right = new TreeNode("E");
        root.right.left = new TreeNode("F");
        root.right.right = new TreeNode("G");
        root.left.left.left = new TreeNode("H");
        root.left.left.right = new TreeNode("I");
        root.left.right.right = new TreeNode("J");
        root.right.left.right = new TreeNode("K");

        // 前序遍历结果:
        System.out.println("前序遍历结果:");
        preorderTraversal(root);

        // 中序遍历结果:
        System.out.println("中序遍历结果:");
        inorderTraversal(root);

        // 后序遍历结果:
        System.out.println("后序遍历结果:");
        postorderTraversal(root);

        // 层序遍历结果:
        System.out.println("层序遍历结果:");
        levelOrderTraversal(root);
    }
}

结果:

前序遍历

在这里插入图片描述
中序遍历:

在这里插入图片描述

后续遍历:

在这里插入图片描述
层序遍历:

在这里插入图片描述

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

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

相关文章

YOLOV5添加 ECA CA SE CBAM 等八种注意力机制(小白可用)

目录 CBAM注意力机制原理及代码实现 代码实现 yaml文件 修改后的结构图 SE注意力机制 SE结构图 完整代码实现 报错 ⭐欢迎大家订阅我的专栏一起学习⭐ &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680;&…

【考研数学】打基础 - 武忠祥《基础篇》vs 李永乐《复习全书》

这个我太有同感了&#xff0c;但是我现在能分清了&#xff0c;绝对给大家讲明白 大家疑惑的是&#xff0c;武忠祥老师的基础阶段为什么有人推荐高等数学基础篇&#xff0c;有人推荐复习全书。所以到底该用哪一个。 其实这是因为武忠祥老师在两个机构干过&#xff0c;在有道的…

前端之用HTML弄一个古诗词

将进酒 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>将进酒</title><h1><big>将进酒</big> 君不见黄河之水天上来</h1><table><tr><td ><img…

C#无法给PLC写入数据原因分析

一、背景 1.1 概述 C#中无法给PLC写入数据的原因有很多&#xff0c;这里分享网络端口号被占用导致无法写入的确认方法 1.2 环境 ①使用三菱PLC ②C#通过网口与PLC进行通讯 二、现象 1.1 代码 通过HslCommunication连接PLC时&#xff0c;连接返回成功&#xff0c;写入返回失败 …

了解O2OA(翱途)开发平台中的VIP应用

使用O2OA(翱途)开发平台可以非常方便地进行项目的业务需求开发与实施&#xff0c;O2OA(翱途)开发平台并不限制实现的系统类型&#xff0c;所以能实现的系统很多&#xff0c;最终呈现的项目成果也是多样性的&#xff0c;可能是OA系统&#xff0c;可能是人力资源管理系统&#xf…

AI写作,一键生成原创文章真高效

AI写作&#xff0c;一键生成原创文章真高效!在当今信息爆炸的时代&#xff0c;写作已成为一项重要的技能。然而&#xff0c;对于许多人来说&#xff0c;写作并不容易。有时我们会面临写作灵感枯竭、时间不足或者缺乏写作能力的困扰。但是&#xff0c;随着人工智能技术的不断进步…

3、设计模式之工厂模式2(Factory)

一、什么是工厂模式 工厂模式属于创建型设计模式&#xff0c;它用于解耦对象的创建和使用。通常情况下&#xff0c;我们创建对象时需要使用new操作符&#xff0c;但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口&#xff0c;使得我们可以在不暴露…

TS271IDT运算放大器芯片中文资料PDF数据手册引脚图图片参数价格功能

产品描述&#xff1a; TS271 是一款低成本、低功耗的单通道运算放大器&#xff0c;设计用于采用单电源或双电源供电。该运算放大器采用意法半导体硅栅CMOS工艺&#xff0c;具有出色的消耗-速度比。该放大器非常适合低功耗应用。 电源可通过引脚 8 和 4 之间连接的电阻器进行外…

Linux:深入文件系统

一、Inode 我们使用ls -l的时候看到的除了看到文件名&#xff0c;还看到了文件元数据。 [rootlocalhost linux]# ls -l 总用量 12 -rwxr-xr-x. 1 root root 7438 "9月 13 14:56" a.out -rw-r--r--. 1 root root 654 "9月 13 14:56" test.c 每行包含7列&…

Win11系统启动VMware上虚拟机蓝屏解决办法

背景 最近有在做一个项目的过程中需要使用虚拟机&#xff0c;用原来装好的的Vmware14打开虚拟机&#xff0c;直接蓝屏了&#xff0c;尝试了如下几种方法来解决&#xff0c;最好用的就是第二种&#xff0c;直接下载最新版本(在软件管家中直接下载)。 虚拟机 目前常用的虚拟机软…

idea+maven+tomcat+spring 创建一个jsp项目

概述&#xff1a;我真服了&#xff0c;这个垃圾学校还在教jsp&#xff0c;这种技术我虽然早会了&#xff0c;但是之前搞的大多都是springboot web类型的&#xff0c;这里我就复习一下&#xff0c;避免以后忘记这种垃圾技术 第一步&#xff1a;创建maven项目 第二步&#xff1a…

Java设计模式:桥接模式

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

【STL】deque双端开口容器

1.关于deque容器说明 deque容器与vector容器差不多&#xff0c;但deque是双端开口容器&#xff0c;可以在两端插入和删除元素 push_front( )//在头部插入 push_back( )//在尾部插入 pop_front( )//在头部删除 pop_back( ) //在尾部删除 其他相应函数与vector差不多&#…

Pytorch入门-TensorBoard

文章目录 WhatHOWSummaryWriter What TensorBoard是TensorFlow自带的一个强大的可视化工具&#xff0c;也是一个Web应用程序套件。 torch.utils.tensorboard 是 PyTorch 提供的一个用于将标量、图像、直方图和其他信息记录到 TensorBoard 中的实用程序包。TensorBoard 是 Tenso…

Pycharm的Project Structure (项目结构)

文章目录 一、Sources二、Tests三、Exeluded四、Namespace packages五、Templates六、Resources 一、Sources 源代码根目录&#xff1a;包含项目的主要源代码&#xff0c;它会在这个目录下搜索代码&#xff0c;然后自动补全和只能提示都通过这里的代码提供。若项目运行自定义代…

rabbitmq-spring-boot-start配置使用手册

rabbitmq-spring-boot-start配置使用手册 文章目录 1.yaml配置如下2.引入pom依赖如下2.1 引入项目resources下libs中的jar包依赖如下2.2引入maven私服依赖如下 3.启动类配置如下4.项目中测试发送消息如下5.项目中消费消息代码示例6.mq管理后台交换机队列创建及路由绑定关系如下…

Java算法总结之冒泡排序(详解)

程序代码园发文地址&#xff1a;Java算法总结之冒泡排序&#xff08;详解&#xff09;-程序代码园小说,Java,HTML,Java小工具,程序代码园,http://www.byqws.com/ ,Java算法总结之冒泡排序&#xff08;详解&#xff09;http://www.byqws.com/blog/3145.html?sourcecsdn 冒泡排序…

(day 7)JavaScript学习笔记(函数1)

概述 这是我的学习笔记&#xff0c;记录了JavaScript的学习过程&#xff0c;我是有一些Python基础的&#xff0c;因此在学习的过程中不自觉的把JavaScript的代码跟Python代码做对比&#xff0c;以便加深印象。在写博客的时候我会尽量详尽的记录每个知识点。如果你完全没接触过J…

社媒营销会遇到的封号问题

最近看到很多的直播都在教伙伴们怎么用linked in 以及facebook开发客户&#xff0c;比如如何添加联系人&#xff0c;如何用添加好友的话术&#xff0c;如何加群&#xff0c;如何分析客户的背景等等。 有的主播只是讲一些表面的东西&#xff0c;有的主播可能是真的肚子里有货&a…

【DataWhale学习】用免费GPU线上跑StableDiffusion项目实践

用免费GPU线上跑SD项目实践 ​ DataWhale组织了一个线上白嫖GPU跑chatGLM与SD的项目活动&#xff0c;我很感兴趣就参加啦。之前就对chatGLM有所耳闻&#xff0c;是去年清华联合发布的开源大语言模型&#xff0c;可以用来打造个人知识库什么的&#xff0c;一直没有尝试。而SD我…