树的前序遍历与中序遍历构造二叉树和树的中序遍历与后序遍历构造二叉树

目录

一.树的前序遍历与中序遍历构造二叉树

1.题目描述

2.问题分析

3.代码实现

二.树的中序遍历与后序遍历构造二叉树

1.题目描述

2.问题分析

3.代码实现

三.问题思考


一.树的前序遍历与中序遍历构造二叉树

1.题目描述

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

力扣:力扣

2.问题分析

我们根据 preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]来分析如何手动构建一颗二叉树

① 首先根据前序遍历的特点,通过preorder我们可知3为根结点,再根据中序遍历的特点,通过inorder 我们可知3为根结点的左子树有{9},右子树有{15,20,7}这些元素

② 因为已经划分了左右子树,再看preorder,此时9为结点3左子树的根结点,20为结点3右子树的根结点,再看inorder ,此时左子树已经完成,结点20的左子树有{15},右子树有{7};

③ 因为已经划分了左右子树,再看preorder,此时15为结点20左子树的根结点,20为结点3右子树的根结点,,此时preorder数组已经遍历完毕,整棵树也已经构建完毕了

手动已经实现了二叉树的构建,其实关键一共就两步,第一步是在前序遍历列表寻找根结点(也就是子树的第一个元素),第二步是在中序遍历寻找根结点的位置,根结点左边为左子树的结点范围,右边为右子树的结点范围.

接下来我们看代码实现(看代码实现的代码),代码递归实现和我们手动实现的顺序不一样,我们是同时寻找左右子树,递归是先构建根结点,然后构建左子树,最后构建右子树,直到全部遍历完成.(按照前序遍历(根左右)的方式)

大致的顺序如下:没有一步步递归,只画出了关键的步骤

 

其实不加    if(index==preorder.length)return null; 判断也没有错,只不过加上更加直观

3.代码实现

    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

    public TreeNode buildTree(int[] preorder, int[] inorder) {
          for (int i = 0; i < inorder.length; ++i) {
            map.put(inorder[i], i);
        }
       return buildTreeHelper(preorder,inorder,0,inorder.length-1);

    }
    int index=0;
    public TreeNode buildTreeHelper(int[] preorder, int[] inorder,int left,int right){
        if(index==preorder.length){
            return null;
        }
        if(left>right){
            return null;
        }
        //1.前序数组的第一个为根结点
        int val=preorder[index++];
        TreeNode root=new TreeNode(val);
        //2.寻找中序遍历的左右子树的范围
        int mid=map.get(val);
        root.left=buildTreeHelper(preorder,inorder,left,mid-1);
        root.right=buildTreeHelper(preorder,inorder,mid+1,right);
        return root;

    }

二.树的中序遍历与后序遍历构造二叉树

1.题目描述

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

力扣:力扣

2.问题分析

我们根据 inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]来分析如何手动构建一颗二叉树

树的中序遍历与后序遍历和前边那个构建二叉树还是有稍微的不同的,但是大体思路是一致的.

中序和后序需要根据后序遍历来选取根结点,根结点是子树结点范围中的最后一个,例如postorder = [9,15,7,20,3]的根结点是最后一个{3};并且代码实现index从后向前遍历,先构建的右子树

① 首先根据后序遍历的特点,通过postorder我们可知3为根结点,再根据中序遍历的特点,通过inorder 我们可知3为根结点的左子树有{9},右子树有{15,20,7}这些元素

② 因为已经划分了左右子树,再看postorder,此时9为结点3左子树的根结点,20为结点3右子树的根结点,再看inorder ,此时左子树已经完成,结点20的左子树有{15},右子树有{7};

③ 因为已经划分了左右子树,再看preorder,此时15为结点20左子树的根结点,20为结点3右子树的根结点,,此时preorder数组已经遍历完毕,整棵树也已经构建完毕了 

由上面可以看出中序和后序构建二叉树和前序和中序构建二叉树的思路是一样的,实现也是一样的,代码递归构建却有很大的不同,代码递归实现和我们手动实现的顺序不一样,我们是同时寻找左右子树,递归是构建根结点,然后构建好右子树,最后构建左子树,直到全部遍历完成.(按照中右左的方式)

 

 

 其实不加    if(index==preorder.length)return null; 判断也没有错,只不过加上更加直观

3.代码实现

    Map<Integer, Integer> map = new HashMap<>();

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for (int i = 0; i < inorder.length; ++i) {
            map.put(inorder[i], i);
        }
        index = postorder.length - 1;
        return findNode(inorder, postorder, 0, inorder.length - 1);

    }

    //这个index是postOrder的index
    int index;

    public TreeNode findNode(int[] inorder, int[] postorder, int left, int right) {
        if (index < 0) {
            return null;
        }
        if (left > right) {
            return null;
        }
        //1.从postorder找到根结点
        int val = postorder[index--];
        TreeNode root = new TreeNode(val);
        //2.从inorder找到左右子树
        Integer mid = map.get(val);
        //3.递归左子树
        root.right = findNode(inorder, postorder, mid+1, right);
        //4.递归右子树
        root.left = findNode(inorder, postorder, left, mid-1);

        return root;

    }

三.问题思考

现在我们思考这样一个问题:我们是否可以根据前序和后序遍历的顺序,来构建一颗二叉树呢?

答案是不行的,我们观察前面两个题目可以知道:我们最关键的在于寻找根结点,并找到它的左子树的结点范围和右子树结点范围,但是根据前序和后序遍历,第一次我们可以找到根结点,但是我们无法判断它的左子树是哪些,右子树是哪些,因此无法根据这两种遍历方式构建一颗二叉树

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

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

相关文章

【机器学习】Logistic回归---学习笔记

Logistic回归学习笔记Logistic回归学习线路预备知识&#xff1a;建议先去B站学习一下信息量&#xff0c;熵&#xff0c;BL散度&#xff0c;交叉熵的概念。Logistic回归的函数模型损失最小化架构分类函数最大概率分类函数阈值分类函数Logistic回归的优化算法梯度下降随机梯度下降…

4.5--计算机网络之基础篇--2.网址到网页解析--(复习+深入)---好好沉淀,加油呀

1.浏览器做的第一步工作是解析 URL 对 URL 进行解析&#xff0c;从而生成发送给 Web 服务器的请求信息 URL? URL 实际上是请求服务器里的文件资源 当没有路径名时&#xff0c;就代表访问根目录下事先设置的默认文件&#xff0c;也就是 /index.html 或者 /default.html 这些文件…

计算机网络复习笔记(三)物理层

文章目录一物理层的基本概念四大特性&#xff1a;两种信号&#xff1a;调制和编码传输介质三大部分二物理层的基本通信技术四种信道复用技术数据的传输方式三OSI模型一物理层的基本概念 四大特性&#xff1a; 机械特性 接口是怎么样的 电气特性 用多少伏的电 功能特性 线路上…

linux基础之计算机基础

一、计算机基础 &#xff08;1) 计算机发展&#xff1a;电子管、晶体管、集成电路、大规模集成电路 &#xff08;2) 冯诺依曼体系&#xff1a;用二进制表示数据和指令&#xff1b; 存储程序控制&#xff0c;程序和数据预先存入存储器&#xff1b; 计算机系统5大部分&#xf…

Python 高级编程(文件操作)

文件&#xff1a;存储在某种长期存储设备上的数据&#xff01;&#xff01;包括&#xff08;硬板 u 盘 移动硬盘 光盘&#xff09; 计算机中临时的数据&#xff1a; 存储在内存中&#xff0c;一旦操作结束&#xff0c;内存中的空间就会被释放 文件&#xff08;特指普通文本&am…

R语言 4.2.2安装包下载及安装教程

[软件名称]:R语言 4.2.2 [软件大小]: 75.6 MB [安装环境]: Win11/Win10/Win7 [软件安装包下载]: https://pan.quark.cn/s/b6f604930d04 R语言软件的GUI界面比较的简陋,只有一个命令行窗口,且每次创建图片都会跳出一个新的窗口,比较的繁琐,我们可以安装RStudio,来更方便的操作R(…

ChatGPT +工业机器人/自动驾驶控制器的一些尝试

ChatGPT 的功能目前已扩展到机器人领域&#xff0c;可以用语言直观控制如机械臂、无人机、家庭辅助机器人等的多个平台。这会改变人机交互的未来形式吗&#xff1f; 你可曾想过用自己的话告诉机器人该做什么&#xff0c;就像对人说话那样&#xff1f; 比如说&#xff0c;只要告…

多个硬盘挂载到同一个目录

同一目录无法重复挂载&#xff0c;后挂载的会覆盖之前挂载的磁盘。但是现在需要将4块磁盘并行挂载&#xff0c;该如何操作呢&#xff1f; 将2块磁盘合并到一个逻辑卷 进行挂载。 基本知识 基本概念PV(Physical Volume)- 物理卷物理卷在逻辑卷管理中处于最底层&#xff0c;它可…

新能源锂电池行业除杂工艺介绍

近年来新能源汽车快速发展对锂电池的需求引发了人们对锂资源的高度关注。由于锂需求不断上升&#xff0c;全球锂资源越来越紧缺&#xff0c;而在生产含锂产品中会有大量废水、废渣。这些废水废渣含有丰富的锂&#xff0c;对其进行回收提锂具有极高的经济利益。在氟化锂生产中会…

文件操作介绍及C语言实现通讯录管理系统3.0最终版(文件操作版本)

文章目录1. 前言2. 文件操作2.1 什么是文件2.2 文件缓冲区2.3 文件指针2.4 文件的打开与关闭2.5 文件的顺序读写3. 优化通讯录3.1 保存通讯录3.2 加载通讯录4. 结尾1. 前言 上一篇文章我们学习了动态内存开辟的相关知识点&#xff0c;并用动态内存函数优化了我们的通讯录&…

【数据库连接,线程,ThreadLocal三者之间的关系】

一、数据库连接与线程的关系 在实际项目中&#xff0c;数据库连接是很宝贵的资源&#xff0c;以MySQL为例&#xff0c;一台MySQL服务器最大连接数默认是100, 最大可以达到16384。但现实中最多是到200&#xff0c;再多MySQL服务器就承受不住了。因为mysql连接用的是tcp协议&…

JAVA:常用API

一.什么是API&#xff1f; API&#xff08;Application Programming Interface&#xff09;&#xff1a;应用程序编程接口。 简单的来说&#xff1a;就是Java帮我们已经写好的方法&#xff0c;我们可以直接使用。 二.有哪些常用的API&#xff1f; Object、Objects、StringB…

二战华为成功上岸,准备了小半年,要个27k应该也算不上很高吧~

先说下我基本情况&#xff0c;本科不是计算机专业&#xff0c;现在是学通信&#xff0c;然后做图像处理&#xff0c;可能面试官看我不是科班出身没有问太多计算机相关的问题&#xff0c;因为第一次找工作&#xff0c;华为的游戏专场又是最早开始的&#xff0c;就投递了&#xf…

二,八,十,十六进制等常用进制详解

总目录 文章目录总目录一、常用进制1、进制基本信息2、各进制的表示形式二、进制转换原理1、其他进制转为十进制计算原理2、十进制转为其他进制计算原理3、二进制&#xff0c;八进制&#xff0c;十六进制之间的转换结语一、常用进制 1、进制基本信息 基数数码名称描述20 和 1…

【C++】| C/C++内存管理

前言&#xff1a; 在上期&#xff0c;我们已经对类和对象的全部知识进行了总结和梳理。在类和对象学习完之后&#xff0c;今天我将给大家呈现的是关于——C/C内存管理的基本知识。 本文目录 1. C/C内存分布 2. C语言中动态内存管理方式 &#xff08;1&#xff09;C语言跟内…

php科研项目申报审批系统

目 录 1 绪论 4 1.1 开发背景 4 1.2 开发意义 4 1.3 相关知识介绍 4 1.3.1 Apache 4 1.3.2 MySQL 5 1.3.3 PHP 6 1.3.4 Dreamweaver CS3 7 1.4 本文所做的工作及组织结构 7 2 系统分析 7 2.1 需求分析 7 2.2 可行性分析 7 2.3 系统界面…

CSDN博客专家证书发放名单(2023年3月已更新)

目录 证书发放频次 6月&#xff08;第一批&#xff09;证书发放名单&#xff08;80位&#xff09; 7月&#xff08;第二批&#xff09;证书发放名单&#xff08;50位&#xff09; 8月&#xff08;第三批&#xff09;证书发放名单&#xff08;54位&#xff09; 9月&#xf…

2个月月活突破1亿,增速碾压抖音,出道即封神的ChatGPT,现在怎么样了?ChatGPT它会干掉测试?

从互联网的普及到智能手机&#xff0c;都让广袤的世界触手而及&#xff0c;如今身在浪潮中的我们&#xff0c;已深知其力。 前阵子爆火的ChatGPT&#xff0c;不少人保持观望态度。现如今&#xff0c;国内关于ChatGPT的各大社群讨论&#xff0c;似乎沉寂了不少&#xff0c;现在…

Prometheus监控实战之Exporter详解

1 exporter是什么&#xff1f; 广义上向prometheus提供监控数据的程序都可以成为一个exporter的&#xff0c;一个exporter的实例称为target, exporter来源主要2个方面&#xff0c;一个是社区提供的&#xff0c;一种是用户自定义的。 2 常用exporter 官方和一些社区提供好多ex…

彻底关闭Windows自动更新

彻底关闭Windows自动更新 目录 彻底关闭Windows自动更新 前言 Windows10彻底关闭自动更新方法步骤&#xff1a; 一、禁用Windows Update服务 二、在组策略里关闭Win10自动更新相关服务 三、禁用任务计划里边的Win10自动更新 四、在注册表中关闭Win10自动更新 前言 我们用…
最新文章