输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不包含重复的数字。例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1,5, 3, 8, 6},则重建出二叉树并输出它的头结点。二叉树结点的定义如下:
struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}
在前序遍历中最前面的数字为根节点,找到跟节点。
然后在中序遍历中确认根节点的位置,根节点左边为左子树,右边为右子树。
然后再次使用递归,确认左右子树。
递归过程中发现序列中只有一个节点时 则证明是叶子节点直接返回。
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre==null || in==null || pre.length ==0 || in.length ==0){
return null;
}
return construct(pre, in, 0, pre.length-1, 0, in.length-1);
}
private TreeNode construct(int [] pre, int [] in, int startIndexPre, int endIndexPre,
int startIndexIn, int endIndexIn){
//前序遍历找到跟节点
TreeNode root = new TreeNode(pre[startIndexPre]);
if(startIndexPre == endIndexPre){
//考虑输入出错的情况
if(startIndexIn == endIndexIn && in[startIndexIn] == in[endIndexIn]){
return root;
}else{
throw new RuntimeException("Invalid input.");
}
}
//中序遍历区分左右子树进行递归
int rootIndexInMid = startIndexIn;
while (root.val != in[rootIndexInMid] && rootIndexInMid<= endIndexIn){
rootIndexInMid++;
}
//考虑是否有找不到的情况
if(rootIndexInMid > endIndexIn){
throw new RuntimeException("Invalid Input");
}
int leftTreeLength = rootIndexInMid-startIndexIn;
if(leftTreeLength >0){
//递归左子树
root.left = construct(pre, in , startIndexPre+1, startIndexPre+leftTreeLength,
startIndexIn, rootIndexInMid-1);
}
if(rootIndexInMid != endIndexIn){
root.right = construct(pre, in , startIndexPre+leftTreeLength+1, endIndexPre,
rootIndexInMid+1, endIndexIn);
//递归右子树
}
return root;
}
}