面试题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;
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值