题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
先序遍历是先遍历父节点,再遍历左子节点,最后是右子节点
中序遍历是先遍历左子节点,再遍历父节点,最后再遍历右子节点
首先我们先看先序遍历,知道根节点是1,再看中序遍历,1的下标是3,所以左子树的元素是4,7,2,右子树的元素是5,3,8,6,递归调用这个算法就能得出解,下面是程序实现
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode treeNode=recursion(pre,0,pre.length-1,in,0,in.length-1);
return treeNode;
}
public TreeNode recursion(int[] pre,int preLeft,int preRight,int[] in,int inLeft,int inRight){
//剩下三个元素,并且中间节点为父节点时返回
if(preRight-preLeft==2 && pre[preLeft]==in[inLeft+1]){
TreeNode treeNode=new TreeNode(pre[preLeft]);
treeNode.left=new TreeNode(pre[preLeft+1]);
treeNode.right=new TreeNode(pre[preLeft+2]);
return treeNode;
}
TreeNode leftNode=null;
TreeNode rightNode=null;
int num=0;
int target=0;
for(int i=inLeft;i<=inRight;i++){
if(pre[preLeft]==in[i]){
num=i-inLeft;
target=i;
//剩下两个节点
if(preRight-preLeft==1){
//剩下节点为父节点和左子节点的情况
if(target==inLeft+1){
TreeNode treeNode=new TreeNode(in[target]);
treeNode.left=new TreeNode(in[target-1]);
return treeNode;
}
//剩下节点为父节点和右子节点的情况
if(target==inLeft){
TreeNode treeNode=new TreeNode(in[target]);
treeNode.right=new TreeNode(in[target+1]);
return treeNode;
}
}
break;
}
}
//处理边界情况
if (target!=inLeft)
treeNode.left=recursion(pre,preLeft+1,preLeft+num,in,target-num,target-1);
if (target!=inRight)
treeNode.right=recursion(pre,preLeft+num+1, preRight,in,target+1,inRight);
return treeNode;
}
}