面试题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;
		}
面试题7:重建二叉树
图一

思路:首先介绍下前序、中序和后序遍历的概念:

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;
	}
}