中序遍历顺序是 中 左 右 后序遍历是左、右、中,因此可以先通过后序遍历得到的序列的最后一个字符得到二叉树的根节点,然后根据根节点利用strtok()函数将中序遍历分为左子树序列和右子树序列 strtok()的用法链接(8条消息) strtok()函数详解!_魏波.的博客-CSDN博客_strtok
然后根据中序遍历切分的左右子树确定序列的长度这里用strlen()计算给定序列的长度,遇到\0便停下,不包括'\0'在内,然后利用得到的序列长度再将后序遍历的左右子树分开,这样便得到了中序遍历和后序遍历的左右子树,然后分别对左子树 右子树进行递归操作。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
char data;
struct node *lchild;
struct node *rchild;
}bitnode,*bitree;
void creattree(bitree &T,char *hou,char *zhong,int len){//后序中序建立二叉树
if(len<=0){T=NULL;return;}
T=(bitree)malloc(sizeof(bitnode)); //动态分配空间
T->data=hou[len-1]; //后序遍历最后一个元素就是二叉树的根
char *p1,*p2,p[2];
p[0]=hou[len-1];
p[1]='\0';
//strtok原理是将str按照delimiters相同的地方将其截断并返回str地址
//这里用于分割中序的左子树右子树
p1=strtok(zhong,p);
p2=strtok(NULL,p);//此时因为上一次使用完后strtok会保存时用过的地址 直接用null就可以
int ln;
if(p1!=NULL) ln=strlen(p1); //获取左子树长度
else ln=0;
char *q1,*q2;
q1=(char*)malloc(sizeof(char)*(ln+1));//动态分配两个空间用来放置左子树和右子树
q2=(char*)malloc(sizeof(char)*(len-ln));
int i;
for(i=0;i<ln;i++)
q1[i]=hou[i]; //将后序遍历的序列末尾的根节点除去,然后将其分成两部分
//前半部分就是根节点的左子树 后半部分就是根节点的右子树
q1[i]='\0';
for(i=ln;i<len-1;i++)
q2[i-ln]=hou[i];
q2[i-ln]='\0';
if(p1==NULL){ //这里是中序分开的左右子树的序列 如果为空那么表示对应的根节点的某个子树为空
T->lchild=NULL;
}
if(p2==NULL){
T->rchild=NULL;
}
//这里是左递归
if(p1!=NULL) {
creattree(T->lchild,q1,p1,ln);//左子树递归,q1是后序遍历分为两端的左子树部分,p1是中序分为两段的左子树
//这里是右子树递归
}
if(p2!=NULL){
creattree(T->rchild,q2,p2,len-ln-1);
}
}
//先序遍历输出 中左右
void pre(bitree T){
if(T==NULL)return;
printf("%c",T->data);
if(T->lchild)pre(T->lchild);
if(T->rchild)pre(T->rchild);
}
int main(){
char *hou,*zhong;
int n;
scanf("%d",&n);
getchar();
hou=(char*)malloc(sizeof(char)*(n+1));
zhong=(char*)malloc(sizeof(char)*(n+1));
scanf("%s",hou);
scanf("%s",zhong);
bitree T;
creattree(T,hou,zhong,n);
pre(T);
}