二叉树的遍历与构建问题

news2024/11/26 9:54:10

目录

一、二叉树遍历

二、从前序与中序遍历序列构造二叉树

三、从中序遍历与后序遍历序列构造二叉树


一、二叉树遍历

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

 通过实例1给定的字符串(先序遍历)能推出该树如下。它的中序遍历就是CDEGDFA。

创建两个方法,一个方法叫inorder用来中序遍历,并且输出中序遍历的结果。另一个方法叫preOrderBuild传入一个前序遍历的字符串str,就能根据前序遍历的方式构造出一颗二叉树并返回构造后的树根节点。

然后在主方法中传入一颗树的根节点按照题目要求进行输出,所有节点在一行内输出TreeNode root = preorderBuild(str);然后调用inorder(root)输出树的中序遍历,然后设置index = 0,再继续下一次的遍历使用。

在preOrderBuild方法前创建一个index变量,用它来记录传入到字符串的第几个位置,创建一个char类型的值cur来存储str在index位置上的值,当cur==‘#’,则证明该位置在树中是空的,index++然后return null即可。如下图中的第一个cur就不是#,所以创建一个TreeNode类型的root传入该值。然后将index++,root.left = preOrderBuild(s),进入下一层递归。

 获得当前位置的将结果存储为root,然后index++,root.left = preOrderBuild(s),进入下一层递归。

然后获得当前位置的将结果存储为root,然后index++,root.left = preOrderBuild(s),进入下一层递归。

 然后就遇到了第一个#号,则直接返回null值,所以C的左子树就是空的,然后root.right = preOrderBuild(s),进入下一层递归。

遇到了#号,返回null值,所以C的右子树也是空的,那么直接返回这颗树,那么B的左子树就是C,然后root.right = preOrderBuild(s),继续递归。

 后面的递归图如下:

 

 

 

 

 

 到这儿位置就把完整的二叉树形成了。

class TreeNode{
    char val;
    TreeNode left;
    TreeNode right;
    public TreeNode(char val){
        this.val = val;
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String s = in.nextLine();
            TreeNode root = preOrderBuild(s);
            inorder(root);
            index  = 0;
            System.out.println();
        }
    }
    public static void inorder(TreeNode root) {
        if(root==null){
            return ;
        }
        inorder(root.left);
        System.out.print(root.val+" ");
        inorder(root.right);
    }
    static int index = 0;
    public static TreeNode preOrderBuild(String s) {
        char cur = s.charAt(index);
        if(cur=='#'){
            index++;
            return null;
        }
        TreeNode root = new TreeNode(cur);
        index++;
        root.left = preOrderBuild(s);
        root.right = preOrderBuild(s);
        return root;
    }
}

二、从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

 前序遍历的第一个结果一定是当前树的根节点,中序遍历的左子树结果在树根的左侧,右子树结果在当前树根的右侧。

不断从前序遍历中取出树根节点,然后去中序遍历中查找当前树根所处的位置pos,他之前的是他的左子树,之后是右子树结点。

创建一个方法buildTreeHelper中借助前序遍历,在中序遍历的[left..right]还原二叉树,返回构造后的树根节点,有两个特殊情况,当left>right,此时区间为空,一个元素都没有直接返回null。当index == inorder.length,此时将整个前序遍历的所有元素全都访问完毕,构造结束,直接返回null。

在buildTree方法中直接返回buildTreeHelper中得到的值即可,传入两个数组、0和inorder的长度-1。

还需要创建一个find方法,即在当前中序遍历结果集中寻找val对应的位置下标,然后返回下标,就证明他之前的元素都是该位置元素的左子树,后面的都是右子树。

在buildTreeHelper方法中,创建一个全局变量index,进入方法,left为0,right为4,判断特殊情况之后,则证明树一定是有结点的,则创建一个TreeNode类型的root来存储preorder的0号下标位置的元素,然后index++,在创建一个变量pos,用来存储find方法找到的位置下标。

 然后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1),left为0,right为0,在创建root存储1号下标位置元素,然后index++,再用find方法寻找下标。

 然后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1),left为0,right为-1,发现left<right,,所以直接返回null,所以9的左子树为null。

然后调用root.right = buildTreeHelper(preorder,inorder,pos+1,right);left为1,right为0发现left(0)<right(-1),所以直接返回null,所以9的右子树也为null,那么直接返回root,所以3的左子树就建立成功了。

  然后root.right = buildTreeHelper(preorder,inorder,pos+1,right),left为2,right为4,在创建root存储2号下标位置元素,然后index++,再用find方法寻找下标。

 然后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1),left为2,right为2,在创建root存储3号下标位置元素,然后index++,再用find方法寻找下标。

  然后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1),left为2,right为1,left>right,所以所以直接返回null,所以15的左子树也为null。

然后调用root.right = buildTreeHelper(preorder,inorder,pos+1,right);left为3,right为2,发现left(0)<right(-1),所以直接返回null,所以15的右子树也为null,那么直接返回root,所以20的左子树就建立成功了。

 root.right = buildTreeHelper(preorder,inorder,pos+1,right);left为4,right为4,在创建root存储4号下标位置元素,然后index++,再用find方法寻找下标。

 然后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1),left为4,right为3,left>right,所以所以直接返回null,所以7的左子树为null。

然后调用root.right = buildTreeHelper(preorder,inorder,pos+1,right);left为5,right为4,发现left>right,所以直接返回null,所以15的右子树也为null,那么直接返回root,所以20的右子树就建立成功了。

 所以将root返回,就得到了一棵完整的二叉树。

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTreeHelper(preorder,inorder,0,inorder.length-1);
    }
    int index = 0;
    public TreeNode buildTreeHelper(int[] preorder, int[] inorder, int left, int right) {
        if(left>right){
            return null;
        }
        if(index==inorder.length){
            return null;
        }
        int rootVal = preorder[index];
        TreeNode root = new TreeNode(rootVal);
        index++;
        int pos = find(root.val,inorder);
        root.left = buildTreeHelper(preorder,inorder,left,pos-1);
        root.right = buildTreeHelper(preorder,inorder,pos+1,right);
        return root;
    }
    private int find(int val, int[] inorder) {
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == val) {
                return i;
            }
        }
        return -1;
    }

三、从中序遍历与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树。

 我们知道后序遍历的导致就是根右左,所以我们创建一个reverse方法来翻转整个postorder数组,仍然也要创建一个find方法来查找当前元素的位置。

然后调用创建的buildTreeHelper方法,整个操作都是和之前一样的,不一样的在于先要调用root.right = buildTreeHelper(preorder,inorder,pos+1,right);后调用root.left = buildTreeHelper(preorder,inorder,left,pos-1);

public TreeNode buildTree(int[] inorder, int[] postorder) {
        postorder = reverse(postorder);
        return buildTreeHelper(postorder,inorder,0,inorder.length-1);
    }
    private int[] reverse(int[] postorder) {
        int[] arr = new int[postorder.length];
        int i = arr.length-1;
        for(int x :postorder){
            arr[i] = x;
            i--;
        }
        return arr;
    }
    int index = 0;
    public TreeNode buildTreeHelper(int[] preorder, int[] inorder, int left, int right) {
        if(left>right){
            return null;
        }
        if(index==inorder.length){
            return null;
        }
        int rootVal = preorder[index];
        TreeNode root = new TreeNode(rootVal);
        index++;
        int pos = find(root.val,inorder);
        root.right = buildTreeHelper(preorder,inorder,pos+1,right);
        root.left = buildTreeHelper(preorder,inorder,left,pos-1);
        return root;
    }
    private int find(int val, int[] inorder) {
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == val) {
                return i;
            }
        }
        return -1;
    }

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

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

相关文章

卡塔尔世界杯壁纸已上线,下载的壁纸清晰度不够?教你修复清晰

当我们无法走入现场感受这场体育盛宴&#xff0c;就用一张张世界杯壁纸回味世界杯的动人瞬间吧&#xff0c;在家云看球&#xff0c;换上卡塔尔世界杯壁纸&#xff0c;用上表情包一样可以过把瘾&#xff0c;一起看看如何获得卡塔尔世界杯的壁纸和表情包吧&#xff01; 如何获得…

基于PLC的矿泉水自动瓶装控制系统设计

目 录 1 绪论 1 1.1研究背景及意义 1 1.2研究现状 2 1.2.1 可编程序逻辑控制器 2 1.2.2 我国自动瓶装存在的问题 2 1.3研究主要内容 3 2 矿泉水自动瓶装总体设计 5 2.1任务的分析 5 2.2硬件方案设计 5 2.3软件方案设计 6 2.3.1经验设计法 6 2.3.2逻辑设计法 6 3 元件器件选择 8…

[附源码]SSM计算机毕业设计学术文献分享网站JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Spring IoC依赖注入-6

1. 依赖注入的模式和模型: Spring 提供了哪些依赖注入的模式和类型? 手动模式 - 配置或者编程的方式&#xff0c;提前安排注入规则 XML资源配置元信息Java 注解配置元信息API 配置元信息 自动模式 - 实现方提供依赖自动关联的方式&#xff0c;按照内建的注入规则 Autowiring …

拓扑排序算法

背景 拓扑排序是啥意思&#xff1f; 拓扑排序是指: 将有向无环图(DAG)展开为一维的执行序列。DAG顾名思义就是有方向的图&#xff0c;下面这张图就简单说明了啥是有向无环图。一般人可能用到这个算法的情况不多&#xff0c;但是刷leetcode的课程表问题肯定遇到过&#xff0c;其…

ShardingJdbcⅡ

序言 在前文的基础上继续梳理一下分片的相关信息.基于shardingsphere-sharding-api:jar:5.2.1的源码,感觉ShardingJdbc的版本变动频繁且比较大cuiyaonan2000163.com 切入口是如下的内容,吐槽下官网的API文档不太够能把事情说清楚: 分片算法 从上面的自定义分片的可选类型我们…

我有两个列表,现在需要找出两个列表中的不同元素,怎么做?

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤秦时明月汉时关&#xff0c;万里长征人未还。大家好&#xff0c;我是皮皮。一、前言前几天在帮助粉丝解决问题的时候&#xff0c;遇到一个简单的小需求&#…

[附源码]Python计算机毕业设计Django的物品交换平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Pandas数据处理100例】(八十五):Pandas将DataFrame数据转化成字典数据

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

git push出现git@github.com: Permission denied (publickey) 解决办法

故障现象 ➜ LKExtentionKit git:(master) ✗ git push --set-upstream origin master gitgithub.com: Permission denied (publickey). 错误&#xff1a;无法读取远程仓库。请确认您有正确的访问权限并且仓库存在。 解决办法 第1步,验证邮箱与GitHub注册时输入的是否一致 …

计算机网络(详解)

文章目录一&#xff0c;计算机网络⑴ 局域网&#xff08;LAN&#xff09;1) 环状拓扑结构2) 星型拓扑结构3) 总线拓扑结构⑵ 城域网&#xff08;MAN&#xff09;⑶ 广域网&#xff08;WAN&#xff09;二&#xff0c;互联网⑴ 互联网是一种计算机网络⑵ 互联网的工作模式⑶ 互联…

Leetcode 907.子数组的最小值之和(中等)

一、题目 1、题目描述 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff0c;因此 返回答案模 10^9 7 。 示例1&#xff1a; 输入&#xff1a;arr [3,1,2,4] 输…

【Paper】2022_离散时间多智能体系统编队-包围控制研究_李博凡

离散时间多智能体系统编队-包围控制研究_李博凡 文章目录第四章 基于间歇控制的离散时间多智能体系统编队-包围控制4.1 引言4.2 基于状态反馈的离散时间间歇多智能体系统编队-包围控制4.2.1 模型描述4.2.2 稳定性分析4.3 基于观测器的离散时间间歇多智能体系统编队-包围控制4.3…

2022最全Hbuilder打包成苹果IOS-App的详解

本文相关主要记录一下使用Hbuilder打包成苹果IOS-App的详细步骤。 介绍一下个人开发者账号&#xff1a; 再说下什么是免费的苹果开发者账号&#xff0c;就是你没交688年费的就是免费账号&#xff0c;如果你想变成付费开发者账号&#xff0c;提交申请付费就行&#xff0c;账号都…

qt中Qtcpserver服务端_qt websocket

0.前言 本文主要讲解 Qt TCP 相关接口的基本应用&#xff0c;一些实践相关的后面会单独写。 TCP 协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。 TCP 通过三次握手来…

Feign的使用

1、Feigin接口&#xff1a; ProductClientService import com.mengxuegu.springcloud.entities.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.anno…

SIMetrix导入MOS管SPICE参数进行仿真的快速方法

问题的提出 在采用SIMetrix 8.3软件进行E类放大器的仿真过程中&#xff0c;用到了NEXPERIA公司的NMOS管器件PMH550UNE, 但在SIMetrix 8.3的库中没有该器件&#xff0c;因此需要导入第三方库文件. 通常的办法是从生产该器件的公司网站上下载器件库文件&#xff0c;导入到SIMet…

MKS上游和下游集成式压力控制器的技术分析及其替代解决方案

摘要&#xff1a;目前的MKS系列集成式压力控制器本质上是一种流量调节和测量装置&#xff0c;无法直接用来进行准确的压力控制&#xff0c;而且MKS压力控制器还存在测量精度不高、压力控制范围有限和对工作介质洁净度要求很高的不足。为此&#xff0c;为了弥补这些不足&#xf…

Java 并发编程之ConcurrentHashMap源码详解

Java 并发编程之ConcurrentHashMap原理详解 文章目录Java 并发编程之ConcurrentHashMap原理详解原理剖析源码剖析一、构造方法分析二、初始化三、put()实现分析四、扩容原理剖析 HashMap通常的实现方式是“数组链表”&#xff0c;这种方式被称为“拉链法”。 ConcurrentHashMa…

K_A08_001 基于 STM32等单片机驱动L298N模块按键控制直流电机启停正反转加减速

目录 一、资源说明 二、基本参数 1、参数 2、引脚说明 三、驱动说明 L298N模块驱动时序 对应程序: ENA ENB输出PWM 四、部分代码说明 接线说明 1、STC89C52RCL298N模块 2、STM32F103C8T6L298N模块 五、基础知识学习与相关资料下载 六、视频效果展示与程序资料获取 七、项…