二叉树的构造(前序+中序)—(后序 + 中序)
思路:要对前序+中序(后序+中序)的构建树的动态过程要了解,思路比较简单,在了解了这个过程之后,理解下面代码就容易了。
过程
参考图:
前序 + 中序:
后序 +中序:
代码如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef char elemtype;
typedef struct node{
elemtype data;
struct node *lchild;//指向左孩子
struct node *rchild;//指向右孩子
}bnode;
//前序与中序遍历创建二叉树
bnode * precreatebt(char *pre, char *in, int n)
{
bnode *s; //用来构造结点
char *p; //p用来指向中序遍历的循环 (指针下标).
int k; //k用来保存每次递归构造左右子树的结点的数量。
//递归出口,递归到根结点的构造。
if(n<=0)
return NULL;
s = (bnode *)malloc(sizeof(bnode));
s->data = *pre; //创建的结点保存前序遍历的每个值。
//下面代码段是求出k的值,求出当前结点的要构造的左子树的结点个数
for(p = in; p<in+n;p++)
if(*p == *pre)
break;
k = p-in;
//下面就是递归构造
s->lchild = precreatebt(pre+1,in,k); //下标都是从0开始
s->rchild = precreatebt(pre+k+1,p+1,n-k-1);//这里pre+k+1这里要+1是不包括当前结点,同理,-1也是一样。
return s;
}
bnode *lastcreatebt(char *last, char *in, int n)
{
bnode *b;//用来构造结点
char *p;
int k;
//递归出口,递归到根结点的构造。
if(n<=0)
return NULL;
char r = *(last+n-1);//r用来保存后序遍历的最后一个结点值 //与上面的前序相比,多了这一步。
b = (bnode *)malloc(sizeof(bnode));
b->data = r;
//下面代码段求k
for(p = in; p<in+n; p++)
if(*p == r) break;
k = p - in;
b->lchild = lastcreatebt(last, in, k); //这里的in从最当前递归构建二叉树的最左边开始。这里的last也是从最开始开始,因为上面的r的操作。
b->rchild = lastcreatebt(last+k, p+1, n-k-1);
return b;
}
//后序递归遍历
void lastorder(bnode * b)
{
if(b!=NULL)
{
lastorder(b->lchild);
lastorder(b->rchild);
printf("%c ",b->data);
}
}
//前序递归遍历
void preorder(bnode * b)
{
if(b!=NULL)
{
printf("%c ",b->data);
lastorder(b->lchild);
lastorder(b->rchild);
}
}
int main()
{
char a[]="ABDGCEF";
char b[]="DGBAECF";
char c[]="GDBEFCA";
int len = strlen(a);
bnode *pbt = precreatebt(a,b,len);
bnode *lbt = lastcreatebt(c,b,len);
printf("前序与中序建立的二叉树的后序遍历:");
lastorder(pbt);
printf("\n后序与中序建立的二叉树的前序遍历: ");
preorder(lbt);
return 0;
}
程序运行如下: