原题
题目描述
输入一棵普通有序树,输出该树的先根次序和后根次序。
输入
第1行:顶点个数n(1≤n≤200)以下含n行,其中第i行(1≤i≤n)的元素依次为结点i的数据值ai。以后各元素为结点i的儿子序列,以0结束。若ai后仅含一个0,则说明结点i为叶子。
输出
第1行:先根序第2行:后根序
样例输入
18
r 2 3 4 0
a 5 6 0
b 7 0
c 8 9 10 0
w 0
x 11 12 0
f 0
s 13 14 0
t 0
u 0
d 15 0
e 0
i 16 17 18 0
j 0
h 0
m 0
o 0
n 0
样例输出
r a w x d h e b f c s i m o n j t u
w h d e x a f b m o n i j s t u c r
提示
每个节点的数据信息有可能是个字符串,而不是单个字母。
分析
首先,如果你不知道什么是遍历,点击这里。
这道题就是首先建立一个树。这个树要把他的父亲和他的所有儿子记录下来,so用一个一维数组啦~~
还有,幸好这道题提示了:“每个节点的数据信息有可能是个字符串,而不是单个字母。”否则又有很多童鞋只定义一个char字符吧。
struct tree{
char a[20];//名字
int child[201];//所有的儿子
int father;//父亲
int d;//记录有多少的儿子,顺便辅助child数组
}tree[201];
然后在二叉树遍历的基础上,完成普通有序树的遍历罢了。先根序和后根序分别就是先序、后序遍历罢了。
void first(int x){//先序遍历
if(!x) return;
if(!flag){printf("%s",tree[x].a);flag=1;}
else
printf(" %s",tree[x].a);
for(int i=1;i<=tree[x].d;i++)
first(tree[x].child[i]);
}
void last(int x){//后序遍历
if(!x) return;
for(int i=1;i<=tree[x].d;i++)
last(tree[x].child[i]);
if(!flag){printf("%s",tree[x].a);flag=1;}
else
printf(" %s",tree[x].a);
}
源程序
#include<cstdio>
#include<iostream>
using namespace std;
int n;
bool flag;
struct tree{
char a[20];
int child[201];
int father;
int d;
}tree[201];
void first(int x){
if(!x) return;
if(!flag){printf("%s",tree[x].a);flag=1;}
else
printf(" %s",tree[x].a);
for(int i=1;i<=tree[x].d;i++)
first(tree[x].child[i]);
}
void last(int x){
if(!x) return;
for(int i=1;i<=tree[x].d;i++)
last(tree[x].child[i]);
if(!flag){printf("%s",tree[x].a);flag=1;}
else
printf(" %s",tree[x].a);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
scanf("%s",tree[i].a);
int x;
while(cin>>x&&x){
tree[i].child[++tree[i].d]=x;
tree[x].father=i;
}
}
first(1);
cout<<endl;
flag=0;
last(1);
}