前言
在学习了树,二叉树的相关内容后去写了一下题目,结果发现布置的二叉树的入门题是和前序,中序,后序遍历相关的。(这下我就要搜索不管你链表结构了)
P1305 新二叉树
题目描述
输入一串二叉树,输出其前序遍历。
输入格式
第一行为二叉树的节点数 n。(1≤n≤26)
后面 n 行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。
空节点用 *
表示
输出格式
二叉树的前序遍历。
输入输出样例
输入 #1
6 abc bdi cj* d** i** j**
输出 #1
abdicj
题目分析
将每行视为一个高为2的完美二叉树,那么可以借助链表的思想建立一个存储节点信息的逻辑链表(说穿了就是数组,比较菜是这样的),然后就可以通过递归的方式先查找左子树再查找右子树;若此时查询到的为“*”则说明该节点为叶子节点,return 即可
代码示例
#include <stdio.h>
typedef struct fi{
char a, b;
}f;
char rt, l, r;
f st[200];
void dfs(char rt) {
if(rt == '*' || rt == 0) return ;//0防止hack数据不展示全部节点,进入未标记的空链死循环
printf("%c", rt);
dfs(st[(int)rt].a);
dfs(st[(int)rt].b);
return ;
}
int main() {
int n;
char temp;
scanf("%d", &n);
//getchar();
scanf(" %c %c %c", &rt, &l, &r);
st[(int)rt].a = l, st[(int)rt].b = r;
for(int i = 2; i <= n; i++) {
//getchar();
scanf(" %c", &temp);
scanf(" %c %c", &st[(int)temp].a, &st[(int)temp].b);
//printf("%c%c%c\n", temp,st[(int)temp].a, st[(int)temp].b);
}
//printf("\n\n");
/*for(int i = 'a'; i <= 'z'; i++) {
if(st[(int)i].a != 0){
printf("%c%c%c\n", i,st[(int)i].a, st[(int)i].b);
}
}*/
dfs(rt);
return 0;
}
在代码实现的时候发现getcahr()消去换行符不知道为啥会爆内存,所以只能读入的时候加个空格了
P1827 [USACO3.4] 美国血统 American Heritage
题目描述
农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。
你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。
这是在样例输入和样例输出中的树的图形表达方式:
C
/ \
/ \
B G
/ \ /
A D H
/ \
E F
附注:
- 树的中序遍历是按照左子树,根,右子树的顺序访问节点;
- 树的前序遍历是按照根,左子树,右子树的顺序访问节点;
- 树的后序遍历是按照左子树,右子树,根的顺序访问节点。
输入格式
第一行一个字符串,表示该树的中序遍历。
第二行一个字符串,表示该树的前序遍历。
输出格式
单独的一行表示该树的后序遍历。
输入输出样例
输入
ABEDFCHG CBADEFGH
输出
AEFDBHGC
题目分析
前,中,后序排列的基本知识,但本题也能递归搜索解决,没必要重建树(前 + 中;后 + 中;均能重建树);
代码示例
#include <stdio.h>
#include <string.h>
const int N = 30;
char a[N];//中序
char b[N];//前序
void dfs(int x, int y, int p, int q) { //指针
if(x > y || p > q) return ; //边界
for(int i = x; i <= y; i++){
if(a[i] == b[p]) { //前序首节点为树根
dfs(x, i - 1, p + 1, p + i - x); //拆出该节点对应左子树
dfs(i + 1, y, p + i - x + 1, q); //拆出该节点对应右子树
printf("%c", a[i]); //输出节点
}
}
}
int main() {
scanf("%s", a);
scanf("%s", b);
int len = strlen(a) - 1;
dfs(0, len, 0, len);
return 0;
}