已知前序遍历和中序遍历结果重建二叉树
问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。例如输入的前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出它的二叉树并输出它的头结点。
解题思路
在二叉树的前序遍历中,第一个数字总是树的根节点的值。扫描中序遍历序列,就能确定更节点的值的位置。根据中序遍历的特点,在根节点的值1前面的3个数字 都是左子树节点的值,位于1后面的数字都是右子树的节点的值。
由于在中序遍历序列中,有3个数字是左子树节点的值,因此左子树总共有3个左子节点。同样,在前序遍历的序列中,根节点后面的3个数字是3个左子树节点的值,再后面的所有的数字都是右子树节点的值。这样我们就在前序遍历和和中序遍历两个序列汇总,分别找到了左右子树对应的子序列。然后递归该过程。
public class Code006 {
public static void main(String[] args){
int[] pre={1,2,4,7,3,5,6,8};
int[] in={4,7,2,1,5,3,8,6};
}
public static BinaryTreeNode constructBinaryTree(int[] pre,int[] in){
BinaryTreeNode root=new BinaryTreeNode(pre[0]);//前序遍历的第一个数为跟
int len=pre.length;
if(len==1){
root.pLeft=null;
root.pRight=null;
return root;
}
//找到中序遍历的根位置
int rootValue=root.value;
int i;
for(i=0;i<len;i++){
if(rootValue==in[i]){
break;
}
}
//创建左子树(因为I是从零开始计数的,所以左子树的节点的个数就是i个)
if(i>0){
int[] pr=new int[i];
int[] ino=new int[i];
for(int j=0;j<i;j++){
pr[j]=pre[j+1];
ino[j]=in[j];
}
root.pLeft=constructBinaryTree(pr,ino);
}else {
root.pLeft=null;
}
//创建右子树(右子树节点的个数为len减去左子树节点的个数减去root根节点)
if(len-i-1>0){
int[] pr=new int[len-i-1];
int[] ino=new int[len-i-1];
for(int j=i+1;j<len;j++){
ino[j-i-1]=in[j];
pr[j-i-1]=pre[j];
}
root.pRight=constructBinaryTree(pr,ino);
}else {
root.pRight=null;
}
return root;
}
}
class BinaryTreeNode{
int value;
BinaryTreeNode pLeft;
BinaryTreeNode pRight;
public BinaryTreeNode(int value) {
this.value = value;
}
}