由二叉树的先序+中序、后序+中序、层次+中序都可以唯一的确定一棵二叉树。需要注意的是,如果只知道二叉树的先序序列和后序序列是无法唯一确定一棵二叉树的。
题意:输入某二叉树的先序遍历和中序遍历结果,请重建出该二叉树,并输出它的后序遍历序列。
解题思路:在二叉树的先序遍历中,第一个数字是根结点,在中序遍历中,根结点在序列的中间,左子树在根结点的左边,右子树在根结点的右边。因此可以通过扫描中序序列,找到根结点,可以得到左子树及其右子树的结点集,也即得到了左、右子树的先序遍历序列和中序遍历序列,利用递归的方法来完成。代码如下:
//由遍历序列构造二叉树
//输入某二叉树的先序遍历和中序遍历的结果,请重建出该二叉树。
//假设输入的先序遍历和终序遍历的结果中都不含重复的数字。
<pre name="code" class="cpp">#include<iostream>
using namespace std;
typedef struct BiTreeNode{
int data;
BiTreeNode *lchild;
BiTreeNode *rchild;
}*BiTree;
//函数声明
BiTreeNode* Construct(int *preorder, int *inorder, int length);
BiTreeNode* ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder);
void PostorderPrint(BiTreeNode *root);
void main()
{
int p[]={1,2,4,7,3,5,6,8};
int i[]={4,7,2,1,5,3,8,6};
int *pre=p;//先序序列
int *in=i;//中序序列
int length=8;
BiTreeNode *root=Construct(pre,in,length);
cout<<"construct success!"<<endl;
PostorderPrint(root);
}
//构建一颗二叉树
//已知先序遍历序列preorder,中序遍历序列inorder,以及长度length
BiTreeNode* Construct(int *preorder, int *inorder, int length)
{
if(preorder==NULL || inorder==NULL || length<=0)
return NULL;
return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}
//递归函数,构建一颗二叉树
//参数分别为:startPreorder是先序遍历的始结点,endPreorder是先序遍历的尾结点
//startInorder是中序遍历的始结点,endInorder是中序遍历的尾结点
BiTreeNode* ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
//先序遍历的第一个数字是根结点,首先构造根结点
BiTreeNode *root=new BiTreeNode();
root->data=*startPreorder;
root->lchild=NULL;
root->rchild=NULL;
//递归终止条件:先序遍历中只有一个结点
if(startPreorder==endPreorder)
return root;
//在中序遍历中找到根结点
int *rootInorder=startInorder;
while(rootInorder<=endInorder&&(*rootInorder)!=root->data)
rootInorder++;
if(*rootInorder!=root->data)//非法输入!
exit(0);
int leftlength=rootInorder-startInorder;//左子树的结点数
if(leftlength>0)//左子树不为空,构造左子树
root->lchild=ConstructCore(startPreorder+1,startPreorder+leftlength,startInorder,rootInorder-1);
int rightlength=endInorder-rootInorder;//右子树的结点数
if(rightlength>0)//右子树不为空,构造右子树
root->rchild=ConstructCore(endPreorder-rightlength+1,endPreorder,rootInorder+1,endInorder);
return root;
}
//以后序序列输出
void PostorderPrint(BiTreeNode *root)
{
if(root==NULL)
return;
PostorderPrint(root->lchild);
PostorderPrint(root->rchild);
cout<<root->data<<" ";
}