重建二叉树

重建二叉树

/* 题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。
 * 			假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
 * 			例如:前序遍历为12473568、中序遍历为47215386
 * 			前序遍历的第一个元素为数的根节点、中序遍历中根节点左边的为左子树右边的为右子树
 * 			前序:根节点(1)左子树(247)右子树(3568)
 * 			中序:左子树(472)根节点(1)右子树(5368)
 * 			
 * 			前序247、中序472								前序3568、中序5368
 * 			前序:根节点(2)左子树(47)右子树(null)		前序:根节点(3)左子树(5)右子树(68)
 * 			中序:左子树(47)根节点(2)右子树 null		中序:左子树(5)根节点(3)右子树(68)
 * 			
 * 			前序47、中序47
 * 			前序:根节点(4)左子树(null)右子树(7)
 * 			中序:左子树(null)根节点(4)右子树(7)
 * 
 * 			前序首元为根节点,中序中找到对应元素,左边的为左子树中序、右边的为右子树中序
 * 				若左右子树存在将根节点左孩子指向左子树前序首元、右孩子指向右子树前序首元
 * 			前序中从1开始取length(左子树中序)个元素为左子树前序,剩余的为右子树前序
 * 			将左子树前序、左子树中序继续传入该方法
 * 			将右子树前序、右子树中序继续传入该方法
 * 			
 * 			重建二叉树(前序、中序)
 * 			if(length前序、length中序据为1)该节点为根节点返回。
 * 			根节点=前序首元
 * 			左子树中序=中序[0~根节点]、右子树中序=中序[根节点+1~-1]
 * 			左子树前序=前序[1,length左子树中序]、前序[length左子树中序+1,-1]
 * 			左孩子=重建二叉树(左子树前序、左子树中序)
 * 			右孩子=重建二叉树(右子树前序、右子树中序)
 * 			返回根结点
 * 
 * 			特殊情况:
 * 			只有根节点
 * 			只有左子树或右子树
 * 			空树
 * */

import java.util.Arrays;

public class ChongJianErChaShu {
	public static void main(String[] args) {
		int[] preorder = {3,9,20,15,7};
		int[] inorder = {9,3,15,20,7};
		ChongJianErChaShu_Solution solution = new ChongJianErChaShu_Solution();
		TreeNode root = solution.buildTree(preorder, inorder);
		System.out.println("aaaaa");
		ChongJianErChaShu.iteratorTree(root);
	}
	
	static public void iteratorTree(TreeNode root) {
		if(root == null) return ;
		System.out.println(root.val);
		iteratorTree(root.left);
		iteratorTree(root.right);
	}
}

class ChongJianErChaShu_Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    	//如果是空树直接返回
    	if(preorder.length==0&&inorder.length==0) return null;
        //叶子结点返回
    	if(preorder.length==1&&inorder.length==1) {
    		return new TreeNode(preorder[0]);
    	}
    	//根节点等于前序首元
    	TreeNode root = new TreeNode(preorder[0]);
    	//根据根节点、划分左子树中序、右子树中序
    	//声明中序根节点索引
    	int innorderIndex = 0;
    	for (int i = 0; i < inorder.length; i++) {
			if(inorder[i] == root.val) {
				innorderIndex = i;
				break;
			}
		}
    	//声明左右子树前序中序
    	int[] leftInorder = Arrays.copyOfRange(inorder, 0, innorderIndex);
    	int[] rightInorder = Arrays.copyOfRange(inorder, innorderIndex+1,inorder.length);
    	int[] leftPreorder = Arrays.copyOfRange(preorder, 1, 1+leftInorder.length);
    	int[] rightPreorder = Arrays.copyOfRange(preorder, 1+leftInorder.length, preorder.length);
    	TreeNode leftChild = buildTree(leftPreorder, leftInorder);
    	TreeNode rightChild = buildTree(rightPreorder, rightInorder);
    	root.left = leftChild;
    	root.right = rightChild;
    	return root;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值