面试题7:重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建图一所示的二叉树并输出它的头节点。二叉树节点定义如下:
class BinaryTreeNode{
int value;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
public BinaryTreeNode(int value,BinaryTreeNode left,BinaryTreeNode right) {
this.value=value;
this.leftNode=left;
this.rightNode=right;
}
思路:首先介绍下前序、中序和后序遍历的概念:
1)前序:先访问根节点,再访问左子节点,最后访问右子节点
2)中序:从先问左子节点,再访问根节点,最后访问右子节点
3)后序:先访问左子节点,再访问右子节点,最后访问根节点
此题:前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
思路继续:所以前序遍历的第一个节点肯定是根节点,在中序中根节点左边肯定是左子节点,右边是右子节点,回到此题:
1)根节点是1,从中序知道:左子树是4 7 2,右子树是5 3 8 6
2)从前序知道:节点2是树4 7 2的根节点,从中序知道:节点2的左子树是4 7,没有右子树
3)从前序知道,节点4是树4 7的根节点,从中序知道:节点4没有左子树,右子树是7
4)根节点的右子树以此类推
所以此题可以用类推来做。
解法:
package question7;
import java.util.Arrays;
public class TreeCreate {
static class BinaryTreeNode{
int value;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
public BinaryTreeNode(int value,BinaryTreeNode left,BinaryTreeNode right) {
this.value=value;
this.leftNode=left;
this.rightNode=right;
}
}
public static void main(String[] args) {
int[] preOrders={1,2,4,7,3,5,6,8};
int[] inOrders={4,7,2,1,5,3,8,6};
BinaryTreeNode tree=createBinaryTree(preOrders,inOrders);
System.out.println(tree.value);
System.out.println(tree.leftNode.value);
System.out.println(tree.rightNode.value);
}
private static BinaryTreeNode createBinaryTree(int[] preOrders, int[] inOrders) {
if(preOrders.length==0||inOrders.length==0){
return null;
}
BinaryTreeNode node = new TreeCreate.BinaryTreeNode(preOrders[0],null,null);
int index=indexOfArray(inOrders,preOrders[0]);
node.leftNode=createBinaryTree(Arrays.copyOfRange(preOrders, 1, 1+index), Arrays.copyOfRange(inOrders, 0, index));
node.rightNode=createBinaryTree(Arrays.copyOfRange(preOrders, index+1, preOrders.length), Arrays.copyOfRange(inOrders, index+1,inOrders.length));
return node;
}
private static int indexOfArray(int[] preOrders, int num) {
if(preOrders==null||preOrders.length<=0){
System.out.println("数组为空");
return -1;
}
for(int i=0;i<preOrders.length;i++){
if(num==preOrders[i]){
return i;
}
}
return -1;
}
}