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

解题所需的知识

二叉树的遍历

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

二叉树的先序遍历

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

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

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

​ 找到了小二叉树的根节点,按照先序再走左,发现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显然就是最上面的那个根节点,中序是中间遍历根节点,那么显然可以得出如下图

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

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

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

代码实现

​ 人用迭代,神用递归

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

​ 那么现在我们把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(根据前序中序构建二叉树)

    根据前序中序构建二叉树. 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(第十周)二叉树(前序中序推后续)递推实现

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

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

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

  5. 【美国血统 American Heritage 题解】已知前序中序 求后序

    题目: 题目名称:美国血统 American Heritage 题目来源:美国血统 American Heritage ## 题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的 ...

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

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

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

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

  8. YTU 2346: 中序遍历二叉树

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

  9. Leetcode 94. Binary Tree Inorder Traversal (中序遍历二叉树)

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

随机推荐

  1. 微信报错 config:fail.Error:invalid signature

    config:fail.Error:invalid signature 微信公众号报这个错,appid等各项都配置好,经过一番折腾,发现原来ip白明单设置了不是该服务器的ID,重新设置后就可以了

  2. Web发展史

    Web 万维网常称为WWW(World Wide Web)发展至今仅30年,英国计算机科学家,蒂姆 伯纳斯 李爵士 提出了 World Wide Web的设计方案,1990年李爵士完成了Web 所有的 ...

  3. 1 eclipse 离线安装activiti插件

    第一步:下载需要的离线activiti文件: 链接:https://pan.baidu.com/s/1-_XjIsuZfhiEZn6iLul6-Q  密码:mfyk  (这是其他网友的链接) 第二步: ...

  4. 【RL-TCPnet网络教程】第26章 RL-TCPnet之DHCP应用

    第26章     RL-TCPnet之DHCP应用 本章节为大家讲解RL-TCPnet的DHCP应用,学习本章节前,务必要优先学习第25章的DHCP基础知识.有了这些基础知识之后,再搞本章节会有事半功 ...

  5. Java synchronized和 Lock 的区别与用法

    在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方.  ...

  6. Android OpenGL ES 开发(四): OpenGL ES 绘制形状

    在上文中,我们使用OpenGL定义了能够被绘制出来的形状了,现在我们想绘制出来它们.使用OpenGLES 2.0来绘制形状会比你想象的需要更多的代码.因为OpenGL的API提供了大量的对渲染管线的控 ...

  7. [Swift]LeetCode142. 环形链表 II | Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note ...

  8. [Swift]LeetCode621. 任务调度器 | Task Scheduler

    Given a char array representing tasks CPU need to do. It contains capital letters A to Z where diffe ...

  9. 构建multipart/form-data实现文件上传

    构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...

  10. pytthon—day8 读写模式的结合、文件操作模式、with完成文本文件复制、游标操作

    一.读写模式的结合 w:写指没有新建文件,有文件就清空 w=open('1.txt','w',encoding='utf-8') w.write('000\n') 在写入数据时,需要及时处理内存空间, ...