输入某二叉树的前序遍历和中序遍历结果,重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,6,6},则重建出该二叉树并输出它的头结点。
在二叉树的前序遍历序列中,第一个数字总是根节点的值。但在中序遍历序列中,根节点的值位于序列的中间,左子树节点的值位于根节点左边,右子树节点的值位于根节点右边。因此我们需要扫描中序遍历序列,才能找到根节点的值。
找到根节点之后,我们可以确定左右子树节点的值,也得到了左右子树的前序和中序遍历序列,接下来的事情可以用递归完成。
class Node{
int data;
Node lChild;
Node rChild;
}
public class Main{
public static void main(String[] args) {
int[] pre={1,2,4,7,3,5,6,8}; //先序遍历数组
int[] in={4,7,2,1,5,3,6,6}; //中序遍历数组
int length=pre.length;
Node root=construct(pre,in,0,length-1,0,length-1);
System.out.println(root.data);
}
public static Node construct(int[] pre, int[] in, int startPre,int endPre,
int startIn,int endIn) {
if(startPre>endPre||startIn>endIn){ //没有左孩子或右孩子
return null;
}
Node root=new Node();
root.data=pre[startPre]; //先序遍历第一个元素即为根节点
if(startPre==endPre||startIn==endIn){
return root;
}
int rootIndex;
for(rootIndex=startIn;rootIndex<=endIn;rootIndex++){ //找出中序遍历中根节点位置
if(in[rootIndex]==pre[startPre])
break;
}
//根据中序遍历根节点的位置,构造左右子树
//递归构建左子树
root.lChild=construct(pre,in,startPre+1,startPre+rootIndex-startIn,startIn,rootIndex-1);
//递归构建右子树
root.rChild=construct(pre,in,startPre+rootIndex-startIn+1,endPre,rootIndex+1,endIn);
return root;
}
}