剑指offer:(4)树:重建二叉树

35 篇文章 0 订阅
22 篇文章 0 订阅

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

思路:在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历中,根节点的值再序列的中间,左子树的节点的值位于根节点的值的左边而右子树的节点的值位于根节点的值的右边,这样就能够确定左、右子树节点的数量。在前序遍历和中序遍历的序列中划分了左、右子树节点的之后,就可以递归的调用函数reConstructTree,去分别构建它的左右子树。


 

package co.com.jianzhioffer;

import java.util.Scanner;

public class Solution4 {
	
	/*
	 * 内部类:节点
	 */
	private static class TreeNode{
		TreeNode leftChild;
		TreeNode rightChild;
		int data;
		
		TreeNode(int newData){
			leftChild = null;
			rightChild = null;
			data = newData;
		}
	}
	//考虑比较全面,特殊的情况也考虑了
	public static TreeNode reConstructBinaryTree(int[] pre,int[] in){
		if(pre == null || in == null || pre.length!=in.length){
			return null;
		}
		TreeNode root = reConstructBinaryTree(pre,0, pre.length-1,in,0,in.length-1);
		return root;
	}
	/*
	 * 根据二叉树的谦虚遍历和中序遍历来重建二叉树
	 */
	public static TreeNode reConstructBinaryTree(int[] pre,int startPre,int endPre,int[] in,int startIn,int endIn){
		if(startPre>endPre||startIn>endIn){
			return null;
		}
		TreeNode root = new TreeNode(pre[startPre]);
		
		/*
		 * 从中序遍历中找到根节点
		 */
		int i = 0;
		for(i = startIn;i<=endIn;i++){
			if(in[i] == pre[startPre]){
				root.leftChild = reConstructBinaryTree(pre, startPre+1, startPre+i-startIn, in, startIn, i-1);
				root.rightChild = reConstructBinaryTree(pre, startPre+i-startIn+1, endPre, in, i+1, endIn);
				break;
			}
		}
		//没有找到跟节点
		if(i == endIn && in[i] != pre[startPre]){
			return null;
		}
		return root;
	}
	/*
	 * 递归前序遍历,只是为了检验。
	 */
    public static void preOrderTraverse(TreeNode node){
    	if(node==null)
    		return;
    	System.out.print(node.data+" ");
    	preOrderTraverse(node.leftChild);
    	preOrderTraverse(node.rightChild);
    }
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int m = sc.nextInt();
		int[] pre = new int[m];
		int[] in = new int[m];
		TreeNode root = null;
		for(int i = 0;i<m;i++){
			pre[i] = sc.nextInt();
		}
		for(int i = 0;i<m;i++){
			in[i] = sc.nextInt();
		}
		root = reConstructBinaryTree(pre, 0, pre.length-1, in, 0, in.length-1);	
		preOrderTraverse(root);;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值