题目描述
输入一串二叉树,输出其前序遍历。
输入格式
第一行为二叉树的节点数 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);
}
可能看起来有那么一丢丢的长,其实很好理解的。