【C语言】数据结构—由遍历序列构造二叉树
实验内容
实现由先序序列和中序序列以及由中序序列和后续序列构造一颗二叉树的功能。
思路:
将先序(后序)的第一个元素(最后一个元素)在中序序列中中找到相应的元素即p,然后记录k = p-in将先序(后序)序列分成两半,前一半(即左子树)k个元素,后一半(即右子树)n-k-1个元素,用递归的算法以此类推
注意的是先序和后序的递归的不同之处,先序的第二次是从第二个元素开始的,所以pre+1,后序的第二次是从倒数第二个元素开始,post依旧指在第一个元素,所以post.
代码:
#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
}BTNode;
//输出二叉树
void DispBTree(BTNode *b)
{
if(b!=NULL)
{
printf("%c",b->data);
if(b->lchild!=NULL || b->rchild != NULL)
{
printf("(");
DispBTree(b->lchild);
if(b->rchild!=NULL) printf(",");
DispBTree(b->rchild);
printf(")");
}
}
}
//销毁二叉树
void DestroyBTree(BTNode *&b)
{
if(b!=NULL)
{
DestroyBTree(b->lchild);
DestroyBTree(b->rchild);
free(b);
}
}
//先序序列与中序序列
BTNode *CreateBT1(char *pre,char *in,int n)
{
BTNode *b;//要构造的二叉树
char *p;
int k;
if(n<=0) return NULL;
b = (BTNode*)malloc(sizeof(BTNode));
b->data = *pre;
for(p=in;p<in+n;p++)
if(*p == *pre)
break;
k = p-in;
b->lchild = CreateBT1(pre+1,in,k);
b->rchild = CreateBT1(pre+k+1,p+1,n-k-1);
return b;
}
//后序序列与中序序列
BTNode *CreateBT2(char *post,char *in,int n)
{
BTNode *b;
char r,*p;
int k;
if(n<=0) return NULL;
r = *(post+n-1);
b = (BTNode*)malloc(sizeof(BTNode));
b->data = r;
for(p = in;p<in+n;p++)
if(*p == r) break;
k = p-in;
b->lchild = CreateBT2(post,in,k);
b->rchild = CreateBT2(post+k,p+1,n-k-1);
return b;
}
int main()
{
BTNode *b;
ElemType pre[]="ABDEHJKLMNCFGI";
ElemType in[]="DBJHLKMNEAFCGI";
ElemType post[]="DJLNMKHEBFIGCA";
b = CreateBT1(pre,in,14);
printf("先序序列:%s\n",pre);
printf("中序序列:%s\n",in);
printf("构造一颗二叉树为:\n");
printf("括号表示法:");
DispBTree(b);
printf("\n=================================================\n");
b = CreateBT2(post,in,14);
printf("后序序列:%s\n",post);
printf("中序序列:%s\n",in);
printf("构造一颗二叉树为:\n");
printf("括号表示法:");
DispBTree(b);
DestroyBTree(b);
printf("\n");
}