/*
题目:输入一棵二叉树的前序遍历和中序遍历,构建这棵二叉树
前序遍历:1,2,4,7,3,5,6,8
中序遍历:4,7,2,1,5,3,8,6
*/
/*
在二叉树的前序遍历当中,第一个数字总是二叉树的根节点,根据这个数字
我们可以在中序遍历当中找到根节点,在中序遍历的左边所有left个数字
都是左子树,在根节点的右边所有right个数字全都是右子树。
在前序遍历的根节点之后left个数字,就是所有左子树的节点。
前序遍历:1,2,4,7,3,5,6,8
中序遍历:4,7,2,1,5,3,8,6
根据前序遍历,1是根节点,在中序遍历中找到1.
中序遍历1的左边4,7,2全是左子树,右边5,3,8,6全是右子树
递归这个过程就可以重建这棵二叉树
*/
BinaryTreeNode *Construct(int *preorder,int *inorder,int length)
{
if(preorder==nullptr || inorder==nullptr ||length<=0)
return nullptr;
return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}
BinaryTreeNode *ConstructCore
(int *startPreorder,int *endPreorder,
int *startInorder,int *endInorder
)
{
int rootValue=startPreorder[0];
BinaryTreeNode *root=new BinaryTreeNode();
root->value=rootValue;
root->left=root->right=nullptr;
if(startPreorder==endPreorder)
{
if(startInorder==endInorder && *startPreorder==*startInorder)
{
return root;
}
else
{
throw std::exception("Invaild input");
}
}
//在中序遍历中找到根节点的值
int *rootInorder=startInorder;
while(rootInorder<=endInorder && *rootInorder!=rootValue)
{
++rootInorder;
}
if(rootInorder==endInorder && *rootInorder!=rootValue)
throw std::exception("invalid input");
int leftLength=rootInorder-startInorder;
int *leftPreorderEnd=startPreorder+leftLength;
if(leftLength>0)
{
//构建左子树
root->left=ConstructCore(startPreorder+1, leftPreorderEnd, startInorder, rootInorder-1);
}
if(leftLength<endPreorder-startPreorder)
{
//构建右子树
root->right=ConstructCore(leftPreorderEnd+1, endPreorder, rootInorder, endInorder);
}
return root;
}
剑指offer面试题7:重建二叉树
最新推荐文章于 2020-08-17 13:25:00 发布