入门数据结构JAVADS——如何通过遍历顺序构建二叉树

目录

前言

构建二叉树的前提:

为什么需要两个不同类型的遍历:

前序遍历 + 中序遍历 

 我们的算法思路如下:

举例:

 代码实现

后序遍历 + 中序遍历

结尾


前言

入门数据结构JAVA DS——二叉树的介绍 (构建,性质,基本操作等) (1)-CSDN博客

在上一篇博客中,笔者讲过,如果告诉你遍历顺序,是可以通过算法构建出二叉树的,这篇博客就是补充,笔者想具体的阐述一下 "告诉遍历顺序从而构建二叉树" 算法.

构建二叉树的前提:

要唯一地构建出一棵二叉树,至少需要两个不同类型的遍历结果。最常见的组合是:

  1. 前序遍历 + 中序遍历 
  2. 后序遍历 + 中序遍历

只用一种遍历顺序无法唯一地确定一棵二叉树,因为同样的遍历顺序可能对应多个不同的二叉树。下面详细说明这些组合是如何帮助构建二叉树的。

为什么需要两个不同类型的遍历:

  • 中序遍历:中序遍历能够提供节点在二叉树中相对于左右子树的相对位置,但无法告诉你树的层次结构(即节点的父子关系)。例如,如果只知道中序遍历 D B E A F C,我们只能得知顺序关系,但无法区分每个节点的父节点和子节点。

  • 前序遍历 :前序遍历能够提供根节点和子树的先后顺序。它告诉我们哪个节点是根节点,但无法精确地告诉我们左子树和右子树的细节。

  • 后序遍历 :后序遍历提供了叶子节点的顺序以及根节点的最终位置,但同样无法给出左右子树的确切划分。

通俗地说:

  • 中序遍历告诉我们每个节点的左右子树。
  • 前序遍历后序遍历帮助我们找到子根节点。

举个例子:

如果有前序遍历 A B D E C F 和中序遍历 D B E A F C,通过中序遍历可以知道:

  • A 是根节点(因为前序遍历的第一个是根节点)。
  • 在中序遍历中,A 左边的是 D B E,所以这是左子树;A 右边的是 F C,所以这是右子树。

当然,如果告诉你那些位置是空的话,只要一种遍历就够了,可以参考

入门数据结构JAVADS——部分常见的二叉树OJ题目(1) 持续更新-CSDN博客  第四题

前序遍历 + 中序遍历 

笔者通过题目来讲解

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

 我们的算法思路如下:

  1. 确定根节点

    • 前序遍历的第一个元素一定是根节点。根据这个根节点,我们可以在中序遍历中找到根节点的位置,从而确定左右子树。
  2. 划分左右子树

    • 在中序遍历中,根节点左边的元素都是左子树的节点,右边的元素都是右子树的节点。
    • 根据中序遍历的左右划分,再利用前序遍历来确定左右子树的结构。
  3. 递归处理左右子树

    • 对左子树和右子树分别递归重复上述步骤,直到构建完成。

举例:

我们有如下的前序遍历和中序遍历:

  • 前序遍历[A, B, D, E, C, F]
  • 中序遍历[D, B, E, A, F, C]

步骤 1:确定根节点

  • 根据前序遍历的第一个元素,A 是根节点。
  • 在中序遍历中找到 A,可以划分为:
    • 左子树的中序遍历:[D, B, E]
    • 右子树的中序遍历:[F, C]

步骤 2:处理左子树

  • 前序遍历的第二个元素 B 是左子树的根节点。
  • 在左子树的中序遍历 [D, B, E] 中找到 B,可以划分为:
    • 左子树的左子树的中序遍历:[D]
    • 左子树的右子树的中序遍历:[E]

步骤 3:处理右子树

  • 前序遍历中,接下来的是 C,这是右子树的根节点。
  • 在右子树的中序遍历 [F, C] 中找到 C,可以划分为:
    • 左子树的中序遍历:[F](即 C 的左子树)
    • 没有右子树。

   这样处理下来,最后的结构是

       A/ \B   C/ \  /D   E F

 代码实现

我们用这道力扣上的题目来做代码实现

代码如下

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int preindex=0;public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTreeChilde(preorder,inorder,0,inorder.length-1);}// 大体思路,通过中序找子树,通过前序构建每个结点.public TreeNode buildTreeChilde(int[] preorder, int[] inorder,int inbegin,int inend)// begin 和 end 负责检查是否还有结点{if(inbegin>inend){return null ;}TreeNode root = new TreeNode(preorder[preindex]); int rootidx = find(inorder,inbegin,inend,preorder[preindex]);preindex++;root.left = buildTreeChilde( preorder,  inorder, inbegin, rootidx-1);root.right = buildTreeChilde( preorder,  inorder, rootidx+1, inend);return root;}private int find(int [] inorder,int begin,int end,int key){for(int i=0;i<inorder.length;i++){if(inorder[i]==key){return i;}}return -1;}
}

 可以看到,我们设置了 inbegin , inend,rootidx 这三个变量,它们有什么用呢? 

rootidx很简单,每个前序遍历的结点都在中序遍历中有对应位置,rootidx负责定位它,从而将左右子树分割开.

inbegin , inend呢?它们负责确定(子)根结点的左右孩子结点是否是空结点,我们可以看到,每次分割完成以后,对于左右子树来说,如果 inbegin<=inend ,说明还存在结点.如果 inbegin>inend , 那说明已经没有结点了,这很好理解,中序遍历表中  inbegin 已经大于 inend 了, 已经没有结点了.

至于为什么先左后右,则是通过前序遍历的顺序得到的.

通过我们这样的递归,最后就可以构建出二叉树

后序遍历 + 中序遍历

 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

 也差不多是同理,我们如果倒着去看后序遍历表,就可以发现,差不多是  根 -- 右 -- 左 版本的前序遍历,只要稍微改一下代码就好了

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {// 左 右 根public int postordernum=0;public TreeNode buildTree(int[] inorder, int[] postorder){postordernum=postorder.length-1;return buildTreeChild(inorder,postorder,0,inorder.length-1);}public TreeNode buildTreeChild(int[] inorder, int[] postorder,int inbegin,int inend){if(inbegin>inend){return null;}TreeNode root=new TreeNode(postorder[postordernum]);int rootindex=find(inorder,inbegin,inend,postorder[postordernum]);postordernum--;root.right=buildTreeChild(inorder,postorder,rootindex+1,inend);root.left=buildTreeChild(inorder,postorder,inbegin,rootindex-1);return root;}private int find(int [] inorder,int inbegin,int inend,int key){for(int i=inbegin;i<=inend;i++){if(inorder[i]==key){return i;}}return -1;}
}

 从结尾开始反向遍历后序遍历表,然后去构建, 思路基本是一致的.

结尾

笔者是懒狗,创作不易,知识简单,但毕竟用爱发电!

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

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

相关文章

我毕业后的8年嵌入式工作

2015年毕业&#xff0c;2016年工作到现在已经过了8个年头&#xff0c;借着征文&#xff0c;做个简单的回顾与总结。 2015年从广州番禺职业技术学院毕业&#xff0c;学的是嵌入式技术与应用&#xff0c;我的下一届学弟学妹变物联网了&#xff0c;算是绝版专业了吧。出来后谨遵校…

07 设计模式-结构型模式-桥接模式

桥接&#xff08;Bridge&#xff09;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&#xff0c;使得…

JAVA单列集合

List系列集合:添加的元素是 有序、可重复、有索引 Set系列集合:添加的元素是 无序、不重复、无索引 Collection Collection是单列集合的接口&#xff0c;它的功能是全部单列集合都可以继承使用的 public boolean add(E e) 把给定的对象添加到当前集合中 public void …

Spring MVC(下)

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多JavaEE知识 目录 1.响应 1.1 返回静态页面 1.2 返回数据ResponseBody 1.3 返回HTML代码⽚段 1.4 返回JSON 1.5 设置状态码 1.6 设置Header 2 . …

【文献及模型、制图分享】基于国际湿地城市视角的常德市湿地保护修复成效与归因分析及其政策启示

文献介绍 《湿地公约》提出的“国际湿地城市”认证是促进湿地保护修复的新举措。以国际湿地城市常德市为例&#xff0c;基于2000—2022年15 m空间分辨率湿地分类数据&#xff0c;监测常德市湿地保护修复逐年动态变化&#xff0c;定量分析湿地保护修复驱动因素的重要性和贡献率…

K8s中TSL证书如何续期

TSL是什么 K8s中的作用是什么&#xff1f; 在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c;TSL 指的是 Transport Layer Security&#xff0c;也就是传输层安全协议。它是用来保护在网络上传输的数据的安全性和隐私性。 TSL 在 Kubernetes 中的作用包括&#xff1a;…

第1讲(ASP.NET Core 6 Web Api 开发入门):第一个Web Api项目

一、运行模板项目 二、验证模板项目的api 法1&#xff1a;直接在网页上进行验证api 法2&#xff1a;通过命令行验证api 复制下图的Curl语句&#xff0c;打开命令行进行粘贴。&#xff08;对于windows系统&#xff0c;需要把换成"&#xff0c;再去掉所有的/&#xff0c;最…

一文了解AOSP是什么?

一文了解AOSP是什么&#xff1f; AOSP基本信息 基本定义 AOSP是Android Open Source Project的缩写&#xff0c;这是一个由Google维护的完全免费和开放的操作系统开发项目。它是Android系统的核心基础&#xff0c;提供了构建移动操作系统所需的基本组件。 主要特点 完全开源…

【景观生态学实验】实验一 ArcGIS地理数据处理及制图基础

实验目的 1.掌握ArcGIS软件基本操作&#xff1a;通过实验操作与学习&#xff0c;熟练掌握ArcGIS软件相关的基本操作&#xff0c;包括界面熟悉、工具栏使用、数据的加载和保存、基本数据处理操作等; 2.掌握如何使用ArcGIS进行影像拼接及裁剪&#xff1a;通过实验操作与学习&am…

传知代码-ChatGPT多模态命名实体识别

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 ChatGPT辅助细化知识增强&#xff01; 多模态命名实体识别&#xff08;MNER&#xff09;最近引起了广泛关注。 用户在社交媒体上生成大量非结构化内容&#xff0c;主要由图像和文本组成。这些帖子具有与社交媒体相…

GISBox vs CesiumLab:哪款GIS工具更适合你的项目?

在地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;越来越多的用户开始关注GIS工具箱的选择&#xff0c;其中GISBox和CesiumLab是两款备受推崇的产品。那么&#xff0c;哪一款更适合你的需求呢&#xff1f;本文将从功能、使用体验和应用场景等方面&#xff0c;对GISBo…

产品如何实现3D展示?具体步骤如下

产品实现3D展示主要依赖于先进的3D建模与展示技术。以下是产品实现3D展示的具体步骤和方法&#xff1a; 一、3D建模 使用专业的3D建模软件&#xff0c;如Blender、Maya、3ds Max等&#xff0c;这些软件提供了丰富的建模工具和材质编辑器&#xff0c;能够创建出高精度的3D模型…

Python基于amazon/chronos-t5-base的预训练模型离线对时间系列数据的未来进行预测

Python基于预训练模型对时间系列数据的未来进行预测 导入库 %matplotlib inline import matplotlib.pyplot as plt import numpy as np import pandas as pd import torch from chronos import ChronosPipeline from tqdm.auto import tqdm from autogluon.timeseries import…

电脑定期运行某个程序

1、右键计算机-管理&#xff0c;点击任务计划程序&#xff0c;再点击创建基本任务&#xff1b; 2、写名称&#xff0c;下一步 3、选择任务开始计划&#xff0c;下一步 4、选择触发时间&#xff0c;下一步 5、选择启动程序&#xff0c;下一步 6、选择运行的程序&#xff0c;下一…

模型拆解(一):DBINet、GCPANet、CPD、ACCoNet、FPS-U2Net

文章目录 一、DBINet1.1编码器模块&#xff1a;ResNet50PVT双分支结构1.2解码器模块&#xff1a;自细化模块SR的应用1.3DFM&#xff1a;双分支融合模块1.4转换器模块&#xff1a;调整编码器输出至解码器中1.5深度监督损失函数 二、GCPANet2.1编码器模块&#xff1a;ResNet50主干…

uniapp移动端优惠券! 附源码!!!!

本文为常见的移动端uniapp优惠券&#xff0c;共有6种优惠券样式&#xff08;参考了常见的优惠券&#xff09;&#xff0c;文本内容仅为示例&#xff0c;您可在此基础上调整为你想要的文本 预览效果 通过模拟数据&#xff0c;实现点击使用优惠券让其变为灰色的效果&#xff08;模…

来自骨关节炎计划的膝关节MR图像的自动异常感知3D骨骼和软骨分割|文献速递-基于生成模型的数据增强与疾病监测应用

Title 题目 Automated anomaly-aware 3D segmentation of bones and cartilages in kneeMR images from the Osteoarthritis Initiative 来自骨关节炎计划的膝关节MR图像的自动异常感知3D骨骼和软骨分割 Background 背景 近年来&#xff0c;多个机器学习算法被提出用于图像…

windows|常见的文件伪装方法

几种常见的文件伪装方法&#xff1a; 扩展名伪装unicode字符伪装压缩包伪装隐写术 方法仅限于学习目的&#xff0c;不用于任何恶意或非法用途。 ———— 一、扩展名伪装&#xff1a;假装是另一种类型的文件 修改文件的扩展名&#xff0c;使得文件看起来像其他类型的文件&a…

python常用设计模式,单例模式和工厂设计模式

python常用设计模式&#xff0c;单例和工厂设计模式Demo 单例模式 单例设计模式是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。 应用场景&#xff1a;日志记录、线程池、缓存等 优点&#xff1a; 全局访问&…

洛谷题解 - P1162 填涂颜色

目录 填涂颜色题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示题解思路代码 填涂颜色 题目描述 由数字 0 0 0 组成的方阵中&#xff0c;有一任意形状的由数字 1 1 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2 2 2。例如&#xff1a; 6 6 6\times…