创建二叉树(已知先序和中序或中序和后序)C-数据结构

题目

已知二叉树的先序序列和中序序列或中序序列和后序序列,创建二叉树

思路

先序序列和后序序列可以找到根节点(先序序列根节点在最前面,后序在最后面),然后可以通过中序序列将二叉树分为左子树和右子树,然后根据左子树的节点个数和右子树的节点个数可以得到在先序序列和后序序列中左右子树的根节点,由此递推,可以得到完整的二叉树。

代码

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 10000

typedef struct tree {
	int data;
	struct tree*left;
	struct tree*right;	
}Tree;

void createTree(Tree**t,int *a,int *b,int l1,int r1,int l2,int r2);//先序中序遍历二叉树
void rearPrint(Tree *t);   //后序遍历二叉树 
Tree* createTree1(int *a,int *b,int root,int left,int right); //中序后序创建二叉树
void prePrint(Tree *t);   //先序遍历二叉树 
void LayerOrder(Tree *t);  //层序遍历二叉树

 
int main()
{
	int a[MAXSIZE]={0},b[MAXSIZE]={0};
	int len=0;
	Tree *tree;
	printf("请输入先序序列和中序序列的长度:") ;
	scanf("%d",&len);
	printf("请输入先序序列:") ;
	for(int i=0;i<len;i++){
		scanf("%d",&a[i]);
	}
	printf("请输入中序序列:") ;
	for(int i=0;i<len;i++){
		scanf("%d",&b[i]);
	}
	createTree(&tree,a,b,0,len-1,0,len-1);
	printf("后序遍历二叉树:") ;
	rearPrint(tree);
	printf("\n");
	printf("层序遍历二叉树:") ;
	LayerOrder(tree);
	printf("\n");
	printf("请输入中序序列和后序序列的长度:") ;
	scanf("%d",&len);
	printf("请输入中序序列:") ;
	for(int i=0;i<len;i++){
		scanf("%d",&a[i]);
	}
	printf("请输入后序序列:") ;
	for(int i=0;i<len;i++){
		scanf("%d",&b[i]);
	}
	tree=createTree1(a,b,len-1,0,len-1); 
	printf("先序遍历二叉树:") ;
	prePrint(tree);
	printf("\n");
	printf("层序遍历二叉树:") ;
	LayerOrder(tree);
 } 
 
 void createTree(Tree**t,int *a,int *b,int l1,int r1,int l2,int r2) //先序中序创建二叉树
 {
 	(*t)=(Tree*)malloc(sizeof(Tree));
	 (*t)->data=a[l1];
	 int root=0;
	 for(root=l2;root<=r2;root++){
	 	if(a[l1]==b[root]){
	 		break;
		 }
	 }  
	 if(root-l2!=0){
	 	createTree(&(*t)->left,a,b,l1+1,l1+root,l2,root-1);
	 }else{
	 	(*t)->left=NULL;
	 }
	 if(root-r2!=0){
	 	createTree(&(*t)->right,a,b,r1-(r2-root)+1,r1,root+1,r2);
	 }else{
	 	(*t)->right=NULL;
	 }
	 
 }
Tree* createTree1(int *a,int *b,int root,int left,int right) //中序后序创建二叉树
{
	if(left>right){
		return NULL;
	}
	Tree *t=(Tree*)malloc(sizeof(Tree));
	t->data=b[root];
	int i;
	for(i=left;i<=right;i++) 
	{
		if(b[root]==a[i]) break;
	}
	t->left=createTree1(a,b,root-(right-i)-1,left,i-1);
	t->right=createTree1(a,b,root-1,i+1,right);
	return t;
}
 void rearPrint(Tree *t)   //后序遍历二叉树 
 {
 	if(!t){
 		return;
	 }
	 rearPrint(t->left);
	 rearPrint(t->right);
	 printf("%d ",t->data);
 }
  void prePrint(Tree *t)   //先序遍历二叉树 
 {
 	if(!t){
 		return;
	 }
	 printf("%d ",t->data);
	 prePrint(t->left);
	 prePrint(t->right);
 }
 void LayerOrder(Tree *t)  //层序遍历二叉树
 {
 	if(!t) return;
 	int start=-1,end=0,flag=0;
 	Tree *p[MAXSIZE];
 	p[end]=t;
 	while(start!=end){
 		start++;
 		if(flag){
 			printf(" ");
		 }
		 printf("%d",p[start]->data);
		 flag=1;
		if (p[start]->left) {
            end++;
            p[end] = p[start]->left;
        }
        if (p[start]->right) {
            end++;
            p[end] = p[start]->right;
        }
	 }
 } 

运行结果

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漠–

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值