题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字,例如输入前序遍历序列{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. Linux 获取文件夹下的所有文件

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4129616.html #include <string> #include &l ...

  2. stl::search

    template<class ForwardIt1, class ForwardIt2> ForwardIt1 search(ForwardIt1 first, ForwardIt1 la ...

  3. web浏览器下的缓存 - Etag

    设置浏览器缓存的几种方法: Last-Modified : 服务器上文件的最后修改时间 Etag  : 文件标识 Expiers : 本地缓存目录中文件过期的时间 ( 由服务器指定具体的时间 ) Ca ...

  4. 【Qt】QT5 获取IP地址

    QT获取本机IP地址 #include <QtNetwork/QHostAddress> #include <QtNetwork/QNetworkInterface> #inc ...

  5. eclipse安装ermaster建模插件

    下载ermaster.jar 放到plugins重启eclipse即可

  6. Linux 服务器如何禁止 ping 以及开启 ping

    Linux 默认是允许 ping 响应的,也就是说 ping 是开启的,但 ping 有可能是网络攻击的开始之处,所以关闭 ping 可以提高服务器的安全系数.系统是否允许 ping 由2个因素决定的 ...

  7. php session学习笔记(实例代码)

    http  无状态协议 一个服务器向客户端发送消息的时候有三条信息 一是状态二是头信息三是内容 会话控制 让一个用户访问每个页面,服务器都知道是哪个用户访问 cookie cookie是通过头信息发送 ...

  8. php简单计数器程序(文本计数器、图形计数器)

    分享二个php计数器的例子. 1).文本计数器 <?php $countfile="/count.txt";  //设置保存数据的文件 if (!file_exists($c ...

  9. 外部表查询时出现ORA-29913和ORA-29400错误

    create table t_ext_tab(id char(1),name char(6)) organization external( type oracle_loader default di ...

  10. 为cocos2d-x实现安卓输入框。非全屏,无dialog,绑定到lua

    cocos2d-x官方自带的输入框,简直惨不忍睹,在ios还好,在安卓简直了..用过的都知道... 所以为了用户体验,我们自己搞一个吧.输入框这种东西比较特殊,不像按钮.列表框之类的很容易实现,因为涉 ...