C语言实现还原二叉树

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值