#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
char data;
struct node *lchild,*rchild;
}no;//定义一个结构体
no *xianhezhong(char xianxu[],char zhongxu[],int n)//利用先序和中序建立二叉树
{
char lxian[100],rxian[100],lzhong[100],rzhong[100];
int i,l1=0,l2=0,n1=0,n2=0;//l1为左子树长度,l2为右子树长度
no *T=NULL;//初始化一棵树
if(n==0)//如果什么元素都没有,就是一颗空树
return NULL;
T=(no *)malloc(sizeof(no));
if(T==NULL)
return NULL;
T->data=xianxu[0];//线序序列的第一个元素就是根节点,所以把第一个元素赋值
for(i=0;i<n;i++)
{
if(i<=l1&&zhongxu[i]!=xianxu[0])//没读到根节点前的所有元素都可以赋值给左子树数组
lzhong[l1++]=zhongxu[i];
else if(zhongxu[i]!=xianxu[0])
rzhong[l2++]=zhongxu[i];
}
for(i=1;i<n;i++)
{
if(i<(l1+1))
lxian[n1++]=xianxu[i];
else
rxian[n2++]=xianxu[i];
}
T->lchild=xianhezhong(lxian,lzhong,l1);//这一部分就运用到了递归的思想
T->rchild=xianhezhong(rxian,rzhong,l2);
return T;
}
no *cenghezhong(char cen[],char zhong[],int n)//根据层序和中序创建二叉树
{
char lcen[100],rcen[100],lzhong[100],rzhong[100];
int i,j,l1=0,l2=0,n1=0,n2=0;//l1为左子树长度,l2为右子树长度
no *T=NULL;
if(n==0)//返回空树
return NULL;
T=(no *)malloc(sizeof(no));
if(T==NULL)
return NULL;
T->data=cen[0];
for(i=0;i<n;i++)
{
if(i<=l1&&zhong[i]!=cen[0])
lzhong[l1++]=zhong[i];
else if(zhong[i]!=cen[0])
rzhong[l2++]=zhong[i];
}
for(i=1;i<n;i++)
{
for(j=0;j<l1;j++)
{
if(cen[i]==lzhong[j])
{
lcen[n1++]=cen[i];//现在在构建层序序列左子树
}
}
}
for(i=1;i<n;i++)
{
for(j=0;j<l2;j++)
{
if(cen[i]==rzhong[j])
{
rcen[n2++]=cen[i];
}
}
}
T->lchild=cenghezhong(lcen,lzhong,l1);
T->rchild=cenghezhong(rcen,rzhong,l2);
return T;
}
void xianxubianli(no *T)//先序遍历二叉树(递归)
{
if(T==NULL) return;
printf("%c",T->data);
xianxubianli(T->lchild);
xianxubianli(T->rchild);
}
void zhongxubianli(no *T)//中序遍历二叉树(递归)
{
if(T==NULL) return;
zhongxubianli(T->lchild);
printf("%c",T->data);
zhongxubianli(T->rchild);
}
void houxubianli(no *T)//后序遍历二叉树(递归)
{
if(T==NULL) return;
houxubianli(T->lchild);
houxubianli(T->rchild);
printf("%c",T->data);
}
//层次遍历二叉树
typedef struct que
{
no *base[100];
int front,rear;
}queue;
void cengxubianli(no *T)//层序遍历的思想就是第一个元素不入队,直接打印,然后再把第二层的元素存入,
{
queue q;
q.front=q.rear=0;//初始化队列
no *p;
p=T;
if(T)
{
q.base[q.rear]=T;
q.rear++;
while(q.rear!=q.front)
{
p=q.base[q.front];
printf("%c",p->data);
q.front++;
if(p->lchild)
{
q.base[q.rear]=p->lchild;
q.rear++;
}
if(p->rchild)
{
q.base[q.rear]=p->rchild;
q.rear++;
}
}
}
}
void dapeiyi()
{
no *T;
int i=0;
char xianxu[100],zhongxu[100],ch;
printf("输入先序序列:");
while((ch=getchar())&&ch!='\n')
xianxu[i++]=ch;//这个是用于计算中序序列的长度的
printf("输入中序序列:");
i=0;
while((ch=getchar())&&ch!='\n')
zhongxu[i++]=ch;
T=xianhezhong(xianxu,zhongxu,i);
printf("\t+----------------------------------+\n");
printf("\t|--1-- 先序遍历二叉树 -----------|\n");
printf("\t|--2-- 中序遍历二叉树 -----------|\n");
printf("\t|--3-- 后序遍历二叉树 -----------|\n");
printf("\t|--4-- 层序遍历二叉树 -----------|\n");
printf("\t|--0-- 结束运行 -------------------|\n");
printf("\t+----------------------------------+\n");
while(start(T)!=1);
}
void dapeier()
{
no *T;
int i=0;
char cen[100],zhongxu[100],ch;
printf("输入层次序列:");
while((ch=getchar())&&ch!='\n')
cen[i++]=ch;
printf("输入中序序列:");
i=0;
while((ch=getchar())&&ch!='\n')
zhongxu[i++]=ch;
T=cenghezhong(cen,zhongxu,i);
printf("\t+----------------------------------+\n");
printf("\t|--1-- 先序遍历二叉树 -----------|\n");
printf("\t|--2-- 中序遍历二叉树 -----------|\n");
printf("\t|--3-- 后序遍历二叉树 -----------|\n");
printf("\t|--4-- 层序遍历二叉树 -----------|\n");
printf("\t|--0-- 结束运行 -------------------|\n");
printf("\t+----------------------------------+\n");
while(start(T)!=1);
}
void menu()
{
printf("\t+----------------------------------+\n");
printf("\t|--------- 二叉树的构造 -----------|\n");
printf("\t|--1-- 用先序,中序建立二叉树----|\n");
printf("\t|--2-- 用层序,中序建立二叉树 ---|\n");
printf("\t+--0-- 结束运行 -------------------|\n");
printf("\t+----------------------------------+\n");
int n;
printf("请输入您的操作:");
scanf("%d",&n);
getchar();
switch(n)
{
case 0:
return ;
case 1:
dapeiyi();
break;
case 2:
dapeier();
break;
default:
printf("\n--- 输入功能号表错误 ---\n");
break;
}
getch();//这个是接受任意键的意思
system("cls");
menu();
}
int start(no *T)
{
int n;
printf("请输入您的操作:");
scanf("%d",&n);
if(n==1)
{
printf("先序为:");
xianxubianli(T);
printf("\n");
}
else if(n==2)
{
printf("中序为:");
zhongxubianli(T);
printf("\n");
}
else if(n==3)
{
printf("后序为:");
houxubianli(T);
printf("\n");
}
else if(n==4)
{
printf("层序为:");
cengxubianli(T);
printf("\n");
}
else if(n==0)
return 1;
else
printf("\n--- 错误!! ---\n");
printf("\n");
}
int main()
{
menu();
return 0;
}
C语言实现还原二叉树
最新推荐文章于 2022-04-16 00:06:22 发布