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

利用递归的方法构建,其实没有想象的那么难,主要是理解构建过程就行!!
测试用例:
1)普通二叉树(完全二叉树,不完全二叉树)
2)特殊二叉树(所有结点都没有右子结点的二叉树,所有结点都没有左子节点的二叉树,只有一个结点的二叉树)
3)特殊输入测试(二叉树的根结点指针为null,输入的前序遍历序列和中序遍历序列不匹配)
 
树的类:
package com.yyq;
/**
* Created by Administrator on 2015/9/8.
*/
public class BinaryTreeNode {
int m_nValue;
BinaryTreeNode m_pLeft;
BinaryTreeNode m_pRight; public BinaryTreeNode(int m_nValue){
this.m_nValue = m_nValue;
} public BinaryTreeNode getM_pRight() {
return m_pRight;
} public void setM_pRight(BinaryTreeNode m_pRight) {
this.m_pRight = m_pRight;
} public BinaryTreeNode getM_pLeft() {
return m_pLeft;
} public void setM_pLeft(BinaryTreeNode m_pLeft) {
this.m_pLeft = m_pLeft;
} public int getM_nValue() {
return m_nValue;
} public void setM_nValue(int m_nValue) {
this.m_nValue = m_nValue;
}
}

实现类:

package com.yyq;

import java.util.Arrays;

/**
* Created by Administrator on 2015/9/8.
*/
public class Construct { public static BinaryTreeNode reConstruct(int[] preOrder, int[] inOrder) {
if (preOrder == null || inOrder == null) {
return null;
}
int rootData = preOrder[0];// 前序遍历第一个节点是子节点
BinaryTreeNode root = new BinaryTreeNode(rootData);// 找到跟节点
root.m_pLeft = root.m_pRight = null; //只有一个数字的情况
if (preOrder.length == 1 && inOrder.length == 1) {
if (preOrder[0] == inOrder[0]) {
return root;
} else {
throw new IllegalArgumentException("invalid input");
}
} // 在中序遍历中找到rootData的位置
int rootinIndex = 0;
while (rootinIndex < inOrder.length && rootData != inOrder[rootinIndex]) {
rootinIndex++;
}
if (rootinIndex == inOrder.length && rootData != inOrder[rootinIndex - 1]) {
throw new IllegalArgumentException("invalid input");
} // 有左孩子节点
if (rootinIndex > 0) {
root.m_pLeft = reConstruct(
Arrays.copyOfRange(preOrder, 1, rootinIndex + 1),
Arrays.copyOfRange(inOrder, 0, rootinIndex)); //注意复制从0到rootinIndex,但是不包括rootinIndex
}
// 有右孩子节点
if (rootinIndex < inOrder.length - 1) {
root.m_pRight = reConstruct(
Arrays.copyOfRange(preOrder, rootinIndex + 1, preOrder.length),
Arrays.copyOfRange(inOrder, rootinIndex + 1, inOrder.length));
}
return root;
} // ====================测试代码====================
public static void Test(String testName, int[] preorder, int[] inorder) {
if (testName != null || testName != " ")
System.out.println(testName + " begins:");
if (preorder == null || inorder == null){
return ;
}
System.out.println("The preorder sequence is: ");
int prelen = preorder.length;
for (int i = 0; i < prelen; ++i)
System.out.print(preorder[i] + " ");
System.out.println(); System.out.println("The inorder sequence is: ");
int inlen = inorder.length;
for (int i = 0; i < inlen; ++i)
System.out.print(inorder[i] + " ");
System.out.println(); try {
BinaryTreeNode root = reConstruct(preorder, inorder);
} catch (Exception e) {
e.printStackTrace();
}
} // 普通二叉树
// 1
// / \
// 2 3
// / / \
// 4 5 6
// \ /
// 7 8
void Test1() {
int preorder[]={1, 2, 4, 7, 3, 5, 6, 8};
int inorder[]={4, 7, 2, 1, 5, 3, 8, 6};
Test("Test1", preorder, inorder);
} // 所有结点都没有右子结点
// 1
// /
// 2
// /
// 3
// /
// 4
// /
//
void Test2() {
int preorder[]={1, 2, 3, 4, 5} ;
int inorder[]={5, 4, 3, 2, 1} ;
Test("Test2", preorder, inorder);
} // 所有结点都没有左子结点
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test3() {
int preorder[]={1, 2, 3, 4, 5} ;
int inorder[]={1, 2, 3, 4, 5} ;
Test("Test3", preorder, inorder);
} // 树中只有一个结点
void Test4() {
int preorder[]={1} ;
int inorder[]={1} ;
Test("Test4", preorder, inorder);
} // 完全二叉树
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
void Test5() {
int preorder[]={1, 2, 4, 5, 3, 6, 7} ;
int inorder[]={4, 2, 5, 1, 6, 3, 7} ;
Test("Test5", preorder, inorder);
} // 输入空指针
void Test6() {
Test("Test6", null, null);
} // 输入的两个序列不匹配
void Test7() {
int preorder[]={1, 2, 4, 5, 3, 6, 7} ;
int inorder[]={4, 2, 8, 1, 6, 3, 7} ;
Test("Test7: for unmatched input", preorder, inorder);
} public static void main(String[] args) {
{
Construct construct = new Construct();
construct.Test1();
construct.Test2();
construct.Test3();
construct.Test4();
construct.Test5();
construct.Test6();
construct.Test7();
}
}
}
 
输出结果:
Test1 begins:
The preorder sequence is: 
1  2  4  7  3  5  6  8  
The inorder sequence is: 
4  7  2  1  5  3  8  6  
Test2 begins:
The preorder sequence is: 
1  2  3  4  5  
The inorder sequence is: 
5  4  3  2  1  
Test3 begins:
The preorder sequence is: 
1  2  3  4  5  
The inorder sequence is: 
1  2  3  4  5  
Test4 begins:
The preorder sequence is: 
1  
The inorder sequence is: 
1  
Test5 begins:
The preorder sequence is: 
1  2  4  5  3  6  7  
The inorder sequence is: 
4  2  5  1  6  3  7  
Test6 begins:
Test7: for unmatched input begins:
The preorder sequence is: 
1  2  4  5  3  6  7  
The inorder sequence is: 
4  2  8  1  6  3  7  
java.lang.IllegalArgumentException: invalid input
at com.yyq.Construct.reConstruct(Construct.java:23)
at com.yyq.Construct.reConstruct(Construct.java:44)
at com.yyq.Construct.reConstruct(Construct.java:38)
at com.yyq.Construct.Test(Construct.java:71)
at com.yyq.Construct.Test7(Construct.java:151)
at com.yyq.Construct.main(Construct.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
 
Process finished with exit code 0

P55、面试题6:重建二叉树的更多相关文章

  1. 剑指offer编程题Java实现——面试题6重建二叉树

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

  2. 剑指offer-面试题6.重建二叉树

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

  3. 剑指offer面试题6 重建二叉树(c)

  4. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 package com.xsf.SordF ...

  5. 前端常见算法面试题之 - 重建二叉树[JavaScript解法]

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列[1,2,4,7,3,5,6,8],和中序遍历序列[4,7 ...

  6. 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)

    题目:输入某二叉树的前序遍历和中序遍历的结果.请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...

  7. 《剑指offer》面试题6 重建二叉树 Java版

    (由一个二叉树的前序和中序序列重建一颗二叉树) 书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点.注意前序序列, 它的第一个元素就是二叉树的根节点,后面的元素分为它的左 ...

  8. 剑指Offer:面试题6——重建二叉树(java实现)

    问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不包含重复的数字. 例如: 输入:前序{1,2,4,7,3,5,6,8},中序{4,7,2,1 ...

  9. 【剑指Offer】面试题07. 重建二叉树

    题目 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 ...

  10. 《剑指offer》面试题07. 重建二叉树

    问题描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍 ...

随机推荐

  1. 深度优先算法DFS

    英雄要从H点出发,去解救位于M点的美女. 迷宫的围墙用#表示,带*号的位置表示有杀手埋伏,这些点都是不能走的, 那么英雄要最少走多少步才能解救美女呢? package myalgorithm; imp ...

  2. sizeof() 之 数组

    在平时的编程中,我们会经常用到数组,并且需要知道数组的长度,有时我们可以明确的知道数组的长度,但有时并不,这时,可以借用sizeof(),来获得数组的长度,如下: arrayLength = size ...

  3. ES6学习笔记(九)

    1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突.如果有一种机制 ...

  4. Python变量类型(l整型,长整形,浮点型,复数,列表,元组,字典)学习

    #coding=utf-8 __author__ = 'Administrator' #Python变量类型 #Python数字,python支持四种不同的数据类型 int整型 long长整型 flo ...

  5. win10 安装scrapy

    在win10的环境下安装scrapy,并不能直接按照官网的手册(http://doc.scrapy.org/en/1.0/intro/install.html)一次性安装成功,根据我自己的安装过程中遇 ...

  6. Programming Collective Intelligence

    最近正在拜读 O'reilly出版的Programming Collective Intelligence,准备研究研究搜索引擎了,童鞋们,到时候会考虑公布源码哦!

  7. 【转】#ifdef __cplusplus深度剖析

    原文:http://bbs.ednchina.com/BLOG_ARTICLE_251752.HTM 时常在cpp的代码之中看到这样的代码:     #ifdef __cplusplus extern ...

  8. Device disconnected

    问题:android 调试的时候,Logcat没有任何输出,提示Device  disconnected 解决:Devices -- Reset adb

  9. MySQL Partition分区扫盲

    MySQL从5..3开始支持Partition,你可以使用如下命令来确认你的版本是否支持Partition: mysql> SHOW VARIABLES LIKE '%partition%'; ...

  10. Nginx upstream的5种权重分配方式

    .轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,后端服务器down掉,能自动剔除 .weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况. upstre ...