二叉树的重建过程中必须存在中序序列 ,从先序或者后序中能确定二叉树的根节点,再从中序中确定左右根节点的左右子树,再将左右子树按照之前的方案进行处理;
一:先序序列+中序序列->后序序列
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
using namespace std;
typedef struct Node
{
char chValue;
struct Node *lChild;
struct Node *rChild;
} Node;
//重建二叉树
void Rebuild(char *pPreOrder , char *pInOrder , Node **pRoot , int nTreeLen)
{
int nLeftLen , nRightLen;
char *pLeftEnd;
Node *p;
//边界条件检查
if(!pPreOrder || !pInOrder || !pRoot) return;
if(!(p = (Node *)malloc(sizeof(Node)))) return;
p->chValue = *pPreOrder;
p->lChild = p->rChild = NULL;
*pRoot = p;
if(nTreeLen == 1) return;
//划分左右子数
pLeftEnd = pInOrder;
//cout<<"**"<<pLeftEnd<<endl;
while(*pLeftEnd != *pPreOrder)
{
pLeftEnd++;
}
nLeftLen = (int)(pLeftEnd - pInOrder);
nRightLen = nTreeLen - nLeftLen - 1;
if(nLeftLen) Rebuild(pPreOrder + 1 , pInOrder , &(p->lChild) , nLeftLen);
if(nRightLen) Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1 , &(p->rChild) , nRightLen);
}
//后序遍历
void PostOrder(Node *p)
{
if(p)
{
PostOrder(p->lChild);
PostOrder(p->rChild);
printf("%c",p->chValue);
}
}
int main(void)
{
char PreOrder[32] , InOrder[32];
Node *pTree;
//输入先序和中序序列,求后序序列
while(scanf("%s%s", PreOrder , InOrder) != EOF)
{
Rebuild(PreOrder , InOrder , &pTree , strlen(PreOrder));
PostOrder(pTree);
printf("\n");
}
return 0;
}
二:后
序序列+中序序列->前序序列
#include <iostream>
#include <string.h>
using namespace std;
struct tree
{
char data;
tree *left;
tree *right;
};
tree *Rebuild(char *pos,char *in,int n,int m)
{
tree *b;
int k=0;
char *p,*q,*maxp;
int maxpost,maxin;
if(n<=0)
{
return NULL;
}
maxpost=-1;
for(p=in;p<in+n;p++)
for(q=pos;q<pos+m;q++)
if(*p==*q)
{
k=q-pos;
if(k>maxpost)
{
maxpost=k;
maxp=p;
maxin=p-in;
}
}
b=new tree;
b->data=pos[maxpost];
b->left=Rebuild(pos,in,maxin,m);
b->right=Rebuild(pos,maxp+1,n-maxin-1,m);
return b;
}
void pre(tree *b)
{
if(b)
{
cout<<b->data;
pre(b->left);
pre(b->right);
}
}
int main()
{
char c1[1000],c2[1000];//输入后序加中序 求前序。
while(cin>>c1>>c2)
{
tree *b;
b=Rebuild(c1,c2,strlen(c1),strlen(c2));
pre(b);
cout<<endl;
}
return 0;
}
代码二:
#include<stdio.h>
#include<string.h>
void ReBuild(char *pre, char *in,char *post, int len)
{
if(len>0)
{
int n =strchr(in,post[len-1])-in;
ReBuild(pre+1,in,post,n);
ReBuild(pre+n+1,in+n+1,post+n,len-n-1);
pre[0]=post[len-1];
}
}
int main()
{
char pre[30],in[30],post[30];
int len;
while(~scanf("%s%s",post,in))
{
len=strlen(post);
ReBuild(pre,in,post,len);
pre[len]=0;
puts(pre);
}
}