【题目】
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
【思路】
在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历中,根节点的值在序列的中间,左子树的结点的值位于根节点的值的左边,而右子树的结点的值位于根节点的右边。因此我们需要扫描中序遍历序列,才能找到根节点的值。
如图所示,前序遍历序列的第一个数字1就是根节点的值。扫描中序遍历序列,就能确定根节点的值的位置。根据中序遍历的特点,在根节点的值1前面3个数字都是左子树结点的值,位于1后面的数字都是右子树结点的值。
由于中序遍历序列中,有3个数字是左子树结点的值,因此左子树总共有3个左子结点。同样,在前序遍历的序列中,根节点后面的3个数字就是3个左子树结点的值,再后面的所有数字都是右子树结点的值。这样我们就在前序遍历和中序遍历两个序列中,分别找到了左右子树对应的子序列。

【代码】
//重建二叉树
public static TreeNode reConstructBinaryTree(int[] pre,int[] in){
if(pre==null||in==null||pre.length!=in.length) return null;
return core(pre,0,pre.length-1,in,0,in.length-1);
}
private static TreeNode core(int[] pre, int preStart,
int preEnd, int[] in, int inStart, int inEnd) {
TreeNode node=new TreeNode(pre[preStart]);//先序数组起点就是根节点
if(preStart==preEnd){//只有一个节点
if(inStart!=inEnd || pre[preStart]!=in[inStart]){
System.out.println("input valid");
}
}
int i=0;
while(pre[preStart]!=in[inStart+i]){
i++;//查找中序数组的根节点
}
//构建左子树
if(i==0){
node.left=null;
}else{
node.left=core(pre,preStart+1,preStart+i,in,inStart,inStart+i-1);
}
//构建右子树
if(inStart+i==inEnd){
node.right=null;
}else{
node.right=core(pre,preStart+i+1,preEnd,in,inStart+i+1,inEnd);
}
return node;
}
904

被折叠的 条评论
为什么被折叠?



