Java 重建二叉树 根据前序中序重建二叉树

时间:2023-01-04 21:16:40
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

解题所需的知识

二叉树的遍历

这个先中后,是根据何时遍历根节点命名的,左的优先级大于后,比如先序就先遍历根结点,再遍历左节点,最后遍历右节点,中序同理,先左中根最后右,后序,先左再右后根。

Java 重建二叉树 根据前序中序重建二叉树

二叉树的先序遍历

​ 来! 根据上面的的顺序我们来走一遍,先根再左最后右。

​ 首先,显而意见,1是根节点

Java 重建二叉树 根据前序中序重建二叉树

​ 那么现在往左走,发现 2,4,7 也是一棵二叉树,他也是二叉树,我们可不能区别对待,所以理应也满足先序遍历,先根再左最后右。那么2就是这颗小二叉树的根节点啦。

Java 重建二叉树 根据前序中序重建二叉树

​ 找到了小二叉树的根节点,按照先序再走左,发现4,7也是一棵二叉树,这颗小小二叉树也得满足先序哦,4为根节点,再走左,发现左没了,还记得先序得遍历规则嘛 先根再左后右,左没了那就轮到右啦,所以应该走7了,走完7以后,4,7这棵小小小二叉树算是走完了,走完之后该走2,4,7这颗小二叉树的右节点了,依次类推哦。

先序遍历为 1,2,4,7,3,5,6,8

二叉树的中序遍历

同上 4,7,2,1,5,3,8,6

二叉树的后序遍历

同上 7,4,2,5,8,6,3,1

根据先序,中序构建二叉树

​ 举例 前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}

​ 首先,先序先遍历根节点,那么1显然就是最上面的那个根节点,中序是中间遍历根节点,那么显然可以得出如下图

Java 重建二叉树 根据前序中序重建二叉树

​ 那么继续去前序得数组中找,发现4,7,2最先出现的是2,那显然2是4,7,2的根结点,去中序找,4,7都在2之前,那显然都是2的左子树。

Java 重建二叉树 根据前序中序重建二叉树

​ 再去先序找,发现4先出现,那么4就是4,7的根节点,去中序找,发现7在4的右边,说明是右子树。

Java 重建二叉树 根据前序中序重建二叉树

​ 右子树依次类推。。。。。

代码实现

​ 人用迭代,神用递归

​ 我们用递归的思想,首先先序{1,2,4,7,3,5,6,8},中序{4,7,2,1,5,3,8,6},那么我们找到1是根节点:

Java 重建二叉树 根据前序中序重建二叉树

​ 那么现在我们把4,7,2当成一棵二叉树,那么先序从上面知道是{2,4,7} 中序根据上面也知道是{4,7,2},那接下来跟我们找出1是根节点然后分左右是不是一模一样,只不过先序的数组和中序的数组变了

/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
//前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
public TreeNode reConstructBinaryTree(int[] pre, int[] in) { int len = pre.length; TreeNode root = new TreeNode(pre[0]);
//说明只剩下一个了,表示叶子节点,递归可以退出了
if (pre.length == 1) {
root.left = null;
root.right = null;
return root;
} //中间值 在{4,7,2,1,5,3,8,6} 这个中间值第一次应该是3
int flag = 0;
for (int i = 0; i < len; i++) {
//在中序中找到
if (pre[0] == in[i]) {
flag = i;
break;
}
}
if (flag > 0) {
//左子树的先序
int[] leftPre = new int[flag];
//左子树的中序
int[] leftIn = new int[flag];
for (int j = 0; j < flag; j++) {
leftPre[j] = pre[j + 1];
}
for (int j = 0; j < flag; j++) {
leftIn[j] = in[j];
}
//左子树递归
root.left = reConstructBinaryTree(leftPre, leftIn);
} else {
root.left = null;
}
if (pre.length - flag - 1 > 0) {
//右子树的先序,长度为 总-根-左子树
int[] rightPre = new int[pre.length - 1 - flag];
//右子树的中序
int[] rightIn = new int[pre.length - 1 - flag]; for (int j = flag + 1; j < len; j++) {
//右子树中序,为什么要j-flag-1呢 因为我的rightIn要从0开始 而j是k+1开始的 ,所以很尴尬,只能用j-flag-1
rightIn[j - flag - 1] = in[j]; rightPre[j - flag - 1] = pre[j];
} root.right = reConstructBinaryTree(rightPre, rightIn);
} else {
root.right = null;
} return root; } }

Java 重建二叉树 根据前序中序重建二叉树的更多相关文章

  1. Construct Binary Tree from Preorder and Inorder Traversal&lpar;根据前序中序构建二叉树&rpar;

    根据前序中序构建二叉树. 1 / \ 2 3 / \ / \ 4 5 6 7对于上图的树来说, index: 0 1 2 3 4 5 6 先序遍历为: 6 3 7为了清晰表示,我给节点上了颜色,红色是 ...

  2. 数据结构实习 - problem K 用前序中序建立二叉树并以层序遍历和后序遍历输出

    用前序中序建立二叉树并以层序遍历和后序遍历输出 writer:pprp 实现过程主要是通过递归,进行分解得到结果 代码如下: #include <iostream> #include &l ...

  3. hihocoder&lpar;第十周&rpar;二叉树(前序中序推后续)递推实现

    题目 : 后序遍历 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思 ...

  4. java创建二叉树并实现非递归中序遍历二叉树

    java创建二叉树并递归遍历二叉树前面已有讲解:http://www.cnblogs.com/lixiaolun/p/4658659.html. 在此基础上添加了非递归中序遍历二叉树: 二叉树类的代码 ...

  5. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序&sol;中序&sol;后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  6. LeetCode OJ:Binary Tree Inorder Traversal(中序遍历二叉树)

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...

  7. YTU 2346&colon; 中序遍历二叉树

    原文链接:https://www.dreamwings.cn/ytu2346/2606.html 2346: 中序遍历二叉树 时间限制: 1 Sec  内存限制: 128 MB 提交: 12  解决: ...

  8. Leetcode 94&period; Binary Tree Inorder Traversal &lpar;中序遍历二叉树)

    Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tr ...

  9. 【IT笔试面试题整理】给定二叉树先序中序&comma;建立二叉树的递归算法

    [试题描述]:  给定二叉树先序中序,建立二叉树的递归算法 其先序序列的第一个元素为根节点,接下来即为其左子树先序遍历序列,紧跟着是右子树先序遍历序列,固根节点已可从先序序列中分离.在中序序列中找到 ...

随机推荐

  1. Linux连接Internet

    Linux连接Internet 1. Linux网卡 1.1 查看内核所扑捉到的网卡信息(已经安装到服务器并且被Linux内核识别的网卡) [root@www ~]# dmesg | grep -in ...

  2. Html标签第一课

    <p>段落标签</p> <h1>字体标签,1到6,越来越小</h1>.....<h6></h6><h>标签自动换行 ...

  3. Could not obtain connection metadata

    用hibernate连接数据库出现错误 2010-3-16 17:23:39, 093 [main] WARN [org.hibernate.cfg.SettingsFactory] - Could ...

  4. 自定义 404 与 500 错误页面,URL 地址不会重定向(二)

    上一篇是使用了全局过虑器来实现,还可以使用 HttpApplication 来处理. 参考文章: http://www.cnblogs.com/dudu/p/aspnet_custom_error.h ...

  5. Chrome 插件vimium快捷键大全

    vimium是一款让你在chrome浏览器能方便地使用键盘操作浏览器的插件. 转自:http://www.cnblogs.com/liuyangnuts/p/3474905.html 在当前页中导航 ...

  6. C&num;之使类型参数--泛型

    1.泛型是什么 泛型的就是“通用类型”,它可以代替任何的数据类型,使类型参数化,从而达到只实现一个方法就可以操作多种数据类型的目的. 2.为什么使用泛型 举一个比较两个数大小的例子: 以上例子实现in ...

  7. &lbrack;C&plus;&plus;&rsqb; const与指针的关系

    首先快速复习一些基础. 考虑下面的声明兼定义式: int p = 10; p的基础数据类型是int. 考虑下面的声明兼定义式: const int a = 10; a的基础数据类型是int,a是一个常 ...

  8. Doc2vec实现原理

    论文来源:https://www.eecs.yorku.ca/course_archive/2016-17/W/6412/reading/DistributedRepresentationsofSen ...

  9. Winhex数据恢复学习笔记(三)

    上次对文件系统进行简单的分析,这次就文件的镜像功能做一介绍 1.首先镜像的概念:镜像就是数据的副本,是原来数据在相同位置上以相同的排列模式生成的拷贝,所以镜像可以用来还原原始数据,代替原始数据工作,镜 ...

  10. FCC JS基础算法题&lpar;9&rpar;&colon;Mutations&lpar;比较字符串&rpar;

    题目描述: 如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true.举例,["hello", "Hello"]应该返回true,因为在忽略大 ...