二叉树的构造(前序+中序)---(后序 + 中序)

二叉树的构造(前序+中序)—(后序 + 中序)

思路:要对前序+中序(后序+中序)的构建树的动态过程要了解,思路比较简单,在了解了这个过程之后,理解下面代码就容易了。

过程
在这里插入图片描述

参考图:

前序 + 中序:
在这里插入图片描述

后序 +中序:
在这里插入图片描述

代码如下:

#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;
}

程序运行如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值