参考:B站UP--子烁爱学习(推荐大家观看原视频)
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目解析:
如果是以下的二叉树
前序是1 2 4 5 3 6 7
中序是4 2 5 1 6 3 7

首先分析,前序遍历第一个数字就是根节点,这时候你去中序遍历中找到该数字,那么依据中序遍历原则,在这个数字左边的就是该树的左子树,在这个数字右边的就是该树的右子树。
这时候将左子树的前序和中序遍历拿出,当成一个独立的树,将右子树的前序和中序遍历拿出,当成另一个独立的树然后就重复上面的分析,递归分析直到拿出来的独立的树的左节点是一个叶子节点,右节点也是一个叶子节点,终止递归。成功构建二叉树
依据当前例子的分析,左子树:前序[2 4 5],中序[4 2 5],则可以推出,左子树的根节点是2,左叶子节点4,右叶子节点是5
右子树:前序[3 6 7],中序[6 3 7],则可以推出,左子树的根节点是3,左叶子节点6,右叶子节点是7
代码展示
public TreeNode reConstructBinaryTree(int [] pre,int [] in){
return find(pre,in,0,pre.length-1,0,in.length-1);
}
//1 [2 4 7] [3 5 6 8]
//[4 7 2] 1 [5 3 8 6]
//left和right用于确定左子树和右子树的前序遍历的范围和长度大小,这个例子里就是3和4
//leftin和rightin用于确定左子树和右子树的中序遍历的范围大小,这个例子里就是3和4
public TreeNode find(int[] pre,int[] in,int left,int right,int leftin,int rightin){
//判定left如果大于等于数组长度,就已经遍历到了最右边,这个位置也就是最多左右重合,定义确定的范 围就是1,就是一个节点的数字
if(left>=pre.length || leftin>=in.length || left>right || leftin>rightin){
return null;
}
//确定根节点
int value = pre[left];
TreeNode treeNode = new TreeNode(value);
int count=leftin;
//确定左子树的遍历长度
while(in[count] != value){
count++;
}
count-=leftin;
//确定左子树、右子树前序和中序,递归出完整的子树结构
treeNode.left=find(pre, in, left+1, left+count, leftin, leftin+count-1);
treeNode.right=find(pre,in,left+count+1,right,leftin+count+1,rightin);
return treeNode;
}