这题指的是给定一个前序和一个后序二叉树遍历序列,根据这两个序列构建出这个二叉树。
假设前序为:1 2 4 7 3 5 6 8
中序为:4 7 2 1 5 3 8 6
构建二叉树必须得提供中序,原因就是如果只有前序或者后序是无法确定左右子树的,而中序遍历的准则是遍历左孩子,左孩子为NULL时遍历右孩子。因此,中序列中,在某一i节点的左边,说明此节点在该节点的左边,同理右侧也一样。
构建过程:
前序列pre中pre[0]=1;即为根节点,因此在中序列中查找根节点。中序列头部标记*inorderstart++,直到查找到1为*rootinorder。则左树长度为4,7,2为3。对应的前序列为2,4,7将2,4,7与中序4,7,2按此过程递归下去,同理右侧也一样。
#include <stdio.h>
#include <iostream>
using namespace std;
struct BinaryTreeNode
{
int data;
BinaryTreeNode *lchild;
BinaryTreeNode *rchild;
};
BinaryTreeNode *ConStructCore(int *prestart,int *prend,int *inorderstart,int *inorderend)
{
int rootValue=prestart[0];
BinaryTreeNode* root=new BinaryTreeNode();
root->data=rootValue;
root->lchild=NULL;
root->rchild=NULL;
if(prestart==prend)
{
if(inorderend==inorderstart&&*inorderstart==*inorderend)
return root;
else
throw std::exception();
}
//统计左子树
int *mLeftCourse=inorderstart;
while(mLeftCourse<inorderend&&*mLeftCourse!=rootValue)
mLeftCourse++;
if(mLeftCourse==inorderend&&*mLeftCourse!=rootValue)
throw std::exception();
//计算左子树长度
int lcount=mLeftCourse-inorderstart;
//计算右子树长度
int rcount=inorderend-mLeftCourse;
//左子树终点
int *midend=prestart+lcount;
if(lcount>0)
{
root->lchild=ConStructCore(prestart+1, midend, inorderstart, mLeftCourse-1);
}
if(lcount<prend-prestart)
{
root->rchild=ConStructCore(midend+1, prend, mLeftCourse+1, inorderend);
}
return root;
}
BinaryTreeNode *Construct(int *pre,int *inorder,int length)
{
if(pre==NULL||inorder==NULL||length<=0)
return NULL;
return ConStructCore(pre, pre+length-1, inorder, inorder+length-1);
}
void PrintOrder(BinaryTreeNode *t)
{
if(t==NULL) return;
PrintOrder(t->lchild);
PrintOrder(t->rchild);
printf("%d ",t->data);
}
int main()
{
freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);
int mPrevOrder[1001]; //二叉树的先序遍历
int mInOrder[1001]; //二叉树的中序遍历
int nodeNum ;//节点
while(cin>>nodeNum)
{
for(int i=0;i<nodeNum;i++)
scanf("%d",&mPrevOrder[i]);
for(int i=0;i<nodeNum;i++)
scanf("%d",&mInOrder[i]);
BinaryTreeNode *root=Construct(mPrevOrder, mInOrder, nodeNum);
PrintOrder(root);
printf("\n");
}
return 0;
}