剑指offer面试题6:已知前序遍历及中序遍历重建二叉树

前言:大家都知道,一颗二叉树可以有三种遍历方式,前序,中序及后遍
   历。要重建一颗二叉树至少需要知道它的两种遍历结果,其中中序
   遍历是必不可少的,不然是不能重建出一颗二叉树的。
   
   本题已知前序遍历及中序遍历构建二叉树,那如果已知中序遍历及
   后序遍历重构二叉树,其解题思路相同。
   
思路:先根据前序遍历的第一个值(根节点)找到在中序遍历中根节点的
   位置,以此可判断出中序遍历中,根节点左边的节点为左子树中的
   节点,右边的在右子树中,以此递归构建即可。
   
话不多说,代码如下:

//节点类
public class BinaryTreeNode {
	int value;
	BinaryTreeNode left;
	BinaryTreeNode right;
		
	public BinaryTreeNode() {
		this.value=0;
		this.left=null;
		this.right=null;
	}
	public BinaryTreeNode(int value) {
		this.value=value;
	}
}
public class Main {
	public static void main(String []args) throws Exception {
		Main m=new Main();
		int []preorder= {1,2,4,7,3,5,6,8};
		int []inorder= {4,7,2,1,5,3,8,6};
		int len=preorder.length;
		BinaryTreeNode root=new BinaryTreeNode();
		root=m.Construct(preorder,inorder);
		m.lastorderTravel(root);
	}
	//判断前序及中序遍历是否输入有误
	public BinaryTreeNode Construct(int []preorder,int []inorder)throws Exception {
		if(preorder.length==0||inorder.length==0||preorder.length!=inorder.length) {
			throw new Exception("输入有误无法构成二叉树");
		}
		return ConstructTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
		
	}
	/***********************************
	*重建二叉树,返回二叉树根节点
	*prestart为前序遍历开始位置
	*preend为前序遍历结束位置
	*instart为中序遍历开始位置
	*inend为中序遍历结束位置
	***********************************/
	public BinaryTreeNode ConstructTree(int[] preorder, int[] inorder, 
			int prestart, int preend, int instart, int inend) throws Exception{
		int rootValue=preorder[prestart]; //根节点的值
		BinaryTreeNode root=new BinaryTreeNode(rootValue);
		
		//找到中序遍历中根节点的位置
		int rootinorder=instart;
		for(int i=instart;i<=inend;i++) {
			if(rootValue==inorder[i]) {
				rootinorder=i;
				break;
			}
			if(i==inend&&rootValue!=inorder[i]) {
				throw new Exception("输入有误无法构成二叉树");
			}
		}
		
		int leftlen=rootinorder-instart;//左子树长度
		int leftprelen=prestart+leftlen;//前序遍历中左子树结束位置
		//递归构建二叉树
		if(rootinorder>instart) {
			root.left=ConstructTree(preorder,inorder,
					prestart+1,leftprelen,instart,rootinorder-1);
		}
		if(rootinorder<inend) {
			root.right=ConstructTree(preorder,inorder,
					leftprelen+1,preend,rootinorder+1,inend);
		}
		return root;
	}
	
	//后序遍历输出二叉树
	public void lastorderTravel(BinaryTreeNode root) {
		if(root==null)return;
		if(root.left!=null)lastorderTravel(root.left);
		if(root.right!=null)lastorderTravel(root.right);
		System.out.print(root.value+" ");
	}	
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值