输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
struct BiTreeNode{
int data;
BiTreeNode *lchild;
BiTreeNode *rchild;
};
//重建二叉树的核心部分
BiTreeNode* ConstructCore
(int* preorderStart,int* preorderEnd,
int* inorderStart,int* inorderEnd)
{
//先新建根节点,保证只有一个点时,直接赋值给根节点
int rootValue = preorderStart[0];
BiTreeNode* root = new BiTreeNode();
root->data = rootValue;
root->lchild = root->rchild = NULL;
//判断是否只有一个节点
if(preorderStart == preorderEnd && inorderStart == inorderEnd)
return root;
else
throw std::exception("Invalid input");
//在中序中遍历,找到根节点
int* inorderRoot = inorderStart;
while(inorderRoot <= inorderEnd && *inorderRoot != rootValue)
++inorderRoot;//没遍历到最后且值不等于根
if(inorderRoot == inorderEnd && *inorderRoot != rootValue)
throw std::exception("Invalid input");
int leftLen = inorderRoot - inorderStart;//左子树长度
int* leftpreorderEnd = preorderStart + leftLen;//之后去前序中递归
if(leftLen > 0)
{
//构建左子树
root->lchild = ConstructCore(preorderStart + 1,leftpreorderEnd ,inorderStart,inorderRoot -1);
//前序中左子树,start+1,到左子树长度,中序中左子树长度,开始到根节点
}
if(leftLen < preorderEnd - preorderStart )//只要有右子树
root->rchild = ConstructCore(leftpreorderEnd + 1,preorderEnd,inorderRoot + 1,inorderEnd);//前序中右子树为,左子树长度+1到末尾,中序中为根+1,到end
return root;
}
//
BiTreeNode* Construct(int* preorder,int* inorder,int len)//读入前序中序数组
{
//先判断数组是否为空
if(preorder == NULL || inorder == NULL || len < 1)
return NULL;
return ConstructCore(preorder,preorder + len - 1,inorder,inorder + len - 1);
}
//后序遍历
void Posorder(BiTreeNode* &T)
{
if(T)
{
Posorder(T->lchild);
Posorder(T->rchild);
cout << T->data;
}
else
cout << " ";
}
void DestroyTree(BiTreeNode* pRoot)
{
if(pRoot != NULL)
{
BiTreeNode* pLeft = pRoot->lchild;
BiTreeNode* pRight = pRoot->rchild;
delete pRoot;
pRoot = NULL;
DestroyTree(pLeft);
DestroyTree(pRight);
}
}