题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,3,4,5,6,7}和中序遍历序列{3,2,4,1,6,5,7},则重建二叉树并返回。
解题思路
前序遍历的一个结果是根节点。这样可以根据中序遍历中根节点的位置将二叉树分成两个字树(左子树、右子树),利用递归的思想可以解决这个问题。
实现代码:
/**
* @Description:
* @ClassName algorithm
* @Author: Ruiwen
* @Date: 2021/1/14 21:06
*/
public class Test005 {
//通过传进前序遍历,和中序遍历 重建二叉树(可以输出新建的二叉树的后序遍历)
//递归方法重构树
public static TreeNode reConstructBinaryTree
(int[] pre, int[] in) {
if (pre == null || in == null) {
return null;
}
return ConstructCore(pre, in,
0, pre.length - 1, 0, in.length - 1);
}
//重构二叉树核心代码核心代码
public static TreeNode ConstructCore(int[] pre, int[] in,
int preStart, int preEnd, int inStart, int inEnd) {
//通过前序遍历序列找到根节点,很显然是序列第一个值
//创建根节点
TreeNode root = new TreeNode(pre[preStart]);
root.left = null;
root.right = null;
//当遇到特殊情况
if (preStart == preEnd && inStart == inEnd) {
return root;
}
//通过前序遍历序列所得到的根节点在中序遍历根节点的位置
int rootInorder = 0;
for (rootInorder = inStart; rootInorder <= inEnd; rootInorder++) {
if (in[rootInorder] == pre[preStart])
break;
}
//开始分割左右子树
//左子树长度
int leftTreeLength = rootInorder - inStart;
//右子树长度
int rightTreelength = inEnd - rootInorder;
//开始构建左右子树
//构建左子树
if (leftTreeLength > 0) {
root.left = ConstructCore(pre, in,
preStart + 1, preStart + leftTreeLength,
inStart, rootInorder - 1);
}
//构建右子树
if (rightTreelength > 0) {
root.right = ConstructCore(pre, in,
preStart + leftTreeLength + 1, preEnd,
rootInorder + 1, inEnd);
}
return root;
}
public static void main(String[] args) {
int []pre=new int[]{1,2,3,4,5,6,7};
int []in=new int[]{3,2,4,1,6,5,7};
System.out.println(reConstructBinaryTree(pre, in).val);
}
}