P1305 新二叉树

题目描述

输入一串二叉树,输出其前序遍历。

输入格式

第一行为二叉树的节点数 n。(1≤n≤26)

后面 n行,每一个字母为节点,后两个字母分别为其左右儿子。

空节点用 * 表示

输入输出样例

输入 

6
abc
bdi
cj*
d**
i**
j**

输出 #1

abdicj

二叉树的前序遍历。

我主要说一说我的做法,肯定有别的更好的办法,我这里只陈述我的思路。

首先我们需要了解到二叉树的建树方法。

Bitree *creat()
{
    Bitree *t;
    scanf("%c",&c);
    if(c=='*')
        {t=NULL;return t;}
    t=(Bitree *)malloc(sizeof(Bitree));
    t->a=c;
    t->lchild=creat();
    t->rchild=creat();
    return t;
}

这里给出的是根据前序遍历序列建树的方法。也就是说我们只需要得到前序遍历序列就可以得出它的二叉树,从而按照前序遍历顺序输出就好了。可能……这有点毛病,”为啥要已经求出了前序遍历序列了还得建个树啊?直接输出不就好了吗?“可能有这样的问题,我的回答是,我也很麻啊,我直接得出前序遍历然后输出它不给我对啊。非得我建出二叉树来然后输出才算对……

首先,以字符串给它找出前序遍历序列,而我们需要知道的一个规定是,“空节点用*表示”,即若某点之后的左右子树是*,那么就代表这个节点是叶子节点了。那么首先怎么找出前序遍历序列呢,你看啊,每个节点都会有它的子节点(叶子节点也有以*表示),我们观察一下会发现,如果我们把出现的每个节点之后的子节点接在那个节点的后面,就比如cj*上面的输入例子,abc是第一个,所以就这么接好,然后看第二行,bdi,那么我们把“di”接在abc里的b的后面,即abdic,第三行是cj*,那么我们得出的字符串是abdicj*,依次这样连接出来,最后会得到abd**i**cj*,可以了解得到,这个刚好符合前序遍历创建二叉树的条件,于是我们再给他结合上面的那个建树方法,然后再输出就好了。

代码实现为:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int y;
char b[1000];
typedef struct node{
    char a;
    struct node *lchild;
    struct node *rchild;
}Bitree;
Bitree *h;
Bitree *creat()
{
    Bitree *t;
    if(b[y++]=='*')
        {t=NULL;return t;}
    t=(Bitree *)malloc(sizeof(Bitree));
    t->a=b[y-1];
    t->lchild=creat();
    t->rchild=creat();
    return t;
}
void print(Bitree *t)
{
    if(t==NULL)
        return;
    printf("%c",t->a);
    print(t->lchild);
    print(t->rchild);
}
int main()
{
     int n,c=0;
    char a[30][5];
    scanf("%d\n",&n);
    for(int i=0;i<n;i++)
        gets(a[i]);
    for(int j=0;j<3;j++)
        b[c++]=a[0][j];
    for(int i=1;i<n;i++)
        for(int k=0;k<strlen(b);k++)
            if(b[k]==a[i][0])
            {
                char l[100];
                int p=0;
                for(int i=k+1;i<strlen(b);i++)
                    l[p++]=b[i];
                b[k+1]=a[i][1];b[k+2]=a[i][2];
                int u=k+3;
                for(int i=0;i<p;i++)
                    b[u++]=l[i];
            }
    h=creat();
    print(h);
}

可能看起来有那么一丢丢的长,其实很好理解的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值