题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解答:
struct BinaryTreeNode{
int Value;
BinaryTreeNode Left;
BinaryTreeNode Right;
};
BinaryTreeNode* Construct(int* preorder,int* inorder,int length)
{
//非法输入
if(preorder==NULL||inorder==NULL||length<=0)
return NULL;
//调用ConstructCore函数
return ConstructCore(Preorder,Preorder+length-1,inorder,inoder+length-1);
}
BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder)
{
//利用前序遍历找出根结点
int rootValue=startPreorder[0];//根节点的值
BinaryTreeNode* root=(BinarytreeNode)malloc(sizeof(BinarytreeNode));//创建根节点并为其开辟空间
root->Value=rootValue;//给根节点赋值
root->Left=root->Right=NULL;
if(startPreorder==endPreorder)
{
//只有一个结点的情况
if(startInorder==endInorder&& *startPreorder==*startInorder)
return root;
else
printf("Invalid input!\n");
}
//在中序遍历中找到根节点
int* rootInorder=startInorder;
while(rootInorder<=endInorder&& *rootInorder!=rootValue)
++rootInorder;//在中序遍历序列中找到根节点位置
if(rootInorder==endInorder && *rootInorder!=rootValue)//根节点与先序遍历根结点不一致
printf("Invaild input!\n");
int leftLength==rootInorder-startInorder;//定义左子树长度(中序遍历根结点位置处-起始位置)
int* leftPreordeEnd=startPreorder+leftLength;//左子树末尾处
递归方法创建左右子树
//创建左子树
if(leftLength>0)
{
root->Letf=ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
}
//创建右子数
if(letfLength<endPreorder-startPreorder)
{
root->Right=ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}