题目描述

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

题目代码

/**
* Created by YuKai Fan on 2018/8/17.
*/
public class ReBuildTreeNode {
public static void main(String[] args) {
ReBuildTreeNode rtn = new ReBuildTreeNode();
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
TreeNode treeNode = rtn.reConstructBinaryTree(pre, in);
TreeNode treeNode1 = rtn.reConstructBinaryTree2(pre, 0, pre.length, in, 0, in.length);
System.out.println(treeNode.left.val);
} /*
分析:
前序遍历:root->left->right
中序遍历:left->root->right
所以根据前序遍历可以得到pre[0]就是二叉树的root根节点,在根据中序遍历集合可以得到,该根节点的左边是左子树,右边是右子树
调用递归,可以将得到的前序和中序左子树集合看成一个新的二叉树,与上方同理,调用递归,而右子树也是同理可得。
方法一:
这个方法使用了数组Arrays的API:copyOfRange(array,i,j)方法,可以从i开始到j(不包括j)复制一个array数组,并产生一个新的数组,
用这种方法可以得到该二叉树的左子树和右子树,在调用递归
*/
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre.length == 0 || in.length == 0) {
return null;
}
TreeNode tn = new TreeNode(pre[0]);
for (int i = 0; i < in.length; i++) {
if (in[i] == pre[0]) {
tn.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
tn.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
}
}
return tn;
}
/*
方法二
*/
public TreeNode reConstructBinaryTree2(int [] pre,int sPre, int ePre,int [] in, int sIn, int eIn) {
if (sPre > ePre || sIn > eIn) {
return null;
}
TreeNode tn = new TreeNode(pre[sPre]);
for (int i = sIn; i < eIn; i++) {
if (in[i] == pre[sPre]) {
tn.left = reConstructBinaryTree2(pre,sPre+1, sPre+i-sIn,in,sIn,i-1);
tn.right = reConstructBinaryTree2(pre,sPre+i-sIn+1,ePre,in,i+1,eIn);
}
}
return tn;
}
}
/**
* Created by YuKai Fan on 2018/8/17.
*/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}

题目延伸

二叉树是一种非常重要的数据结构,非常多其他数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,广度遍历即我们寻常所说的层次遍历。由于树的定义本身就是递归定义,因此採用递归的方法去实现树的三种遍历不仅easy理解并且代码非常简洁,而对于广度遍历来说,须要其他数据结构的支撑。比方堆了。所以。对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。

四种基本的遍历思想为:

前序遍历:根结点 ---> 左子树 ---> 右子树

中序遍历:左子树---> 根结点 ---> 右子树

后序遍历:左子树 ---> 右子树 ---> 根结点

层次遍历:仅仅需按层次遍历就可以

一、前序遍历

依据上文提到的遍历思路:根结点 ---> 左子树 ---> 右子树,递归方法

    public void preOrderTraverse1(TreeNode root) {
if (root != null) {
System.out.print(root.val+" ");
preOrderTraverse1(root.left);
preOrderTraverse1(root.right);
}
}

二、中序遍历

依据上文提到的遍历思路:左子树 ---> 根结点 ---> 右子树,递归方法

    public void inOrderTraverse1(TreeNode root) {
if (root != null) {
inOrderTraverse1(root.left);
System.out.print(root.val+" ");
inOrderTraverse1(root.right);
}
}

三、后序遍历

依据上文提到的遍历思路:左子树 ---> 右子树 ---> 根结点

    public void postOrderTraverse1(TreeNode root) {
if (root != null) {
postOrderTraverse1(root.left);
postOrderTraverse1(root.right);
System.out.print(root.val+" ");
}
}

四、层次遍历

层次遍历的代码比較简单。仅仅须要一个队列就可以。先在队列中增加根结点。之后对于随意一个结点来说。在其出队列的时候,訪问之。同一时候假设左孩子和右孩子有不为空的。入队列。代码例如以下:

    public void levelTraverse(TreeNode root) {
if (root == null) {
return;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
System.out.print(node.val+" ");
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}

五、深度优先遍历 事实上深度遍历就是上面的前序、中序和后序。可是为了保证与广度优先遍历相照顾,也写在这。代码也比較好理解,事实上就是前序遍历,代码例如以下:

    public void depthOrderTraverse(TreeNode root) {
if (root == null) {
return;
}
LinkedList<TreeNode> stack = new LinkedList<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
System.out.print(node.val+" ");
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
}

借鉴的博客:https://www.cnblogs.com/llguanli/p/7363657.html

java基础编程——重建二叉树的更多相关文章

  1. 6、50道JAVA基础编程练习题跟答案

    50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 程序分析 ...

  2. MQ java 基础编程

    MQ java 基础编程 编写人:邬文俊 编写时间 : 2006-2-16 联系邮件 : wenjunwu430@gmail.com 前言 通过 2 个多星期对 MQ 学习,在 partner 丁 & ...

  3. 50道JAVA基础编程练习题

    50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析 ...

  4. 50道JAVA基础编程练习题 - 题目

    50道JAVA基础编程练习题[1]题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [2]题目:判断 ...

  5. JAVA基础——编程练习(二)

    JAVA编程练习(二) 今天我为了巩固之前的java基础知识的学习,再次进行实战演习,编写了一个小小的java控制台程序,主要是运用java面向对象的思想来完成这个小项目. 一.项目背景介绍 根据所学 ...

  6. JAVA基础——编程练习(一)

    java编程练习(一) 编程题目: 请根据所学知识,编写一个 JAVA 程序,实现输出考试成绩的前三名. 要求: 1. 考试成绩已保存在数组 scores 中,数组元素依次为 89 , -23 , 6 ...

  7. java基础编程练习

    1.编写程序实现对给定的 4 个整数从大到小的顺序排列. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  8. java基础编程题练习(一)

    1.编程实现用户输入4个整数,按从大到小的顺序排列输出. 思路:将输入的数据存入数组,使用冒泡排序对数组数据进行排序后输出数组 冒泡排序的代码如下: import java.util.Scanner; ...

  9. java基础编程

    java的类和常用编程模式还是要多练习,多手写java代码 return new String(filecontent, encoding); 看懂这个意思了吗?第一次见这个构造函数吧,而String ...

随机推荐

  1. AT2672 Coins

    传送门 按理说想到转化问题之后就不难了吧,可是我还是不会写 一个很容易想到的转化就是差分,将银币数和铜币数都减去金币数,这样就转化为\(x+y+z\)个钱币选\(y\)个银币和\(z\)个铜币的最大数 ...

  2. 4、kvm相关网卡操作(添加、删除)

    查看虚拟机的网卡信息 virsh domiflist privi-server 添加临时网卡 virsh attach-interface privi-server --type bridge --s ...

  3. DateAdapter

    import java.text.SimpleDateFormat;import java.util.Date; import javax.xml.bind.annotation.adapters.X ...

  4. LeetCode 260 Single Number III 数组中除了两个数外,其他的数都出现了两次,找出这两个只出现一次的数

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  5. LeetCode 230 Kth Smallest Element in a BST 二叉搜索树中的第K个元素

    1.非递归解法 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * ...

  6. 借鉴redux,实现一个react状态管理方案

    react状态管理方案有很多,其中最简单的最常用的是redux. redux实现 redux做状态管理,是利用reducer和action实现的state的更新. 如果想要用redux,需要几个步骤 ...

  7. htaccess转换httpd.ini方法及案例参考

    案例1:httpd.ini适合IIS使用,.htaccess适合Apache使用,nginx.conf适合Nginx使用 转换前:httpd.ini [ISAPI_Rewrite] # 3600 =  ...

  8. MS Chart 折线图——去除时间中的时、分、秒,按天统计【转】

    MS Chart 折线图——去除时间中的时.分.秒,按天统计   private void Form2_Load(object sender, EventArgs e){            str ...

  9. Visual Studio 2015 实用插件推荐

    -1000.EntityFramework Reverse POCO Generator(EF Code First 的必备神器) Reverse engineers an existing data ...

  10. Router模块

    一.应用场景 监听浏览器地址栏URL的hash值(#后面的部分)的变化,用正则匹配出参数执行相应的JS方法.URL地址的hash部分充当业务逻辑的分发单位. 示例: <!DOCTYPE html ...