package cn.dzp.flyroc.offer; import java.util.Arrays; public class TreeNodeDemo { /*题目描述:输入某二叉树的前序遍历的结果,请重建出该二叉树 * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 * 例如:输入前序遍历的序列{1,2,4,7,3,5,6,8}和 * 中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回*/ /*思路:先找出根节点,而后利用递归方法构造二叉树 * 在二叉树的前序遍历序列中,第一个数字老是树的根结点的值。 * 但在中序遍历序列中,根结点的值在序列的中间, * 左子树的结点的值位于根结点的值的左边, * 而右子树的结点的值位于根结点的值的右边。 * 所以咱们须要扫描中序遍历序列,才能找到根结点的值。*/ /*先序遍历的第一个元素为根节点,在中序遍历中找到这个根节点,从而能够将中序遍历分为左右两个部分, 左边部分为左子树的中序遍历,右边部分为右子树的中序遍历,进而也能够将先序遍历除第一个元素之外的剩余部分分为两个部分, 第一个部分为左子树的先序遍历,第二个部分为右子树的先序遍历。 由上述分析结果,能够递归调用构建函数,根据左子树、右子树的先序、中序遍历重建左、右子树*/ //代码实现 public static class TreeNode{ //构建树的节点类 int val; TreeNode left; //构建左子树 TreeNode right; //构建右子树 //构造方法 TreeNode(int x){ val = x; } //重写toString方法 public String toString() { return "["+val+"——>"+left+" "+right+"]"; } } //重建二叉树 public static TreeNode reConstructBinaryTree(int[] pre, int[] in){ if (pre == null || in == null){ //判断前序序列和中序序列是否为空 return null; } if (pre.length == 0 || in.length == 0){ //判断前序序列和中序序列的长度是否为0 return null; } if (pre.length != in.length){ //判断前序序列的长度是否等于中序序列 return null; } TreeNode root = new TreeNode(pre[0]); //构建根节点 for (int i = 0; i < pre.length; i++){ //遍历前序序列 if (pre[0] == in[i]){ //判断前序序列的根节点(第一个节点)是否与中序序列的其中一个节点相同 root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), //将数组pre从1开始复制直到i+1 Arrays.copyOfRange(in, 0, i)); //构建左子树; //将数组in从0开始复制到i root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), //将数组从i+1开始复制到数组的最后一个元素 Arrays.copyOfRange(in, i+1, pre.length)); //构建右子树 } } return root; } public static void main(String[] args){ //前序序列 int[] pre = {1,2,4,7,3,5,6,8}; System.out.println("这是前序序列:"+Arrays.toString(pre)); //中序序列 int[] in = {4,7,2,1,5,3,8,6}; System.out.println("这是中序序列:"+Arrays.toString(in)); TreeNode treeNode = reConstructBinaryTree(pre, in); System.out.println("重建后的序列:"+treeNode); } }