数据结构的一道题,二叉树 输入先序序列求中序后序输出与叶节点个数。
大一我还是那个才能边看边写出啊哈算法十几行程序的萌新,学完数据结构,半年后再写程序发现,能够手撸近百行还知道那块出问题。闲言少叙,题目如下:
有两点得注意。
其一是回车问题,T* ct(T* r) 函数是建树,之前自己写了一个有点罗嗦,照输入二叉树先序序列,输出先序,中序,后序序列改了一下,但是多次输入就成了问题,因为他的27行输入(本文第十行)会读入换行符,运行一次回车不会被scanf吃掉,但之后的回车会被当成字符对待。
scanf_s("%c", &c);
应该改为
scanf_s(" %c", &c);
看上去好像没有什么不一样,实际上%c前多了一个空格,在%c之前空格会告诉scanf忽略前面的空行,而等待第一个非空行元素读入其中。参考[scanf读入一个字符避免读入上一个换行符]。
(https://www.cnblogs.com/itsad/p/7903205.html)
另外还找到了一篇scanf的另一些奇巧淫技scanf读取含空格的字符串,说实话c规则太死板了,比如转义问题,参见配置文件中有“路径信息”时,需呀注意的问题(路径中的\是转义字符)
另一个问题是求叶节点个数。
int lnum(T* r) {
if (r == NULL)return 0;
int num;
int n1 = lnum(r->l);
int n2 = lnum(r-> r);
if (n1 == 0 && n2 == 0)
num = 1;
else num = n1 + n2;
return num;
}
总体代码如下,先附上样例
3
a##
ab##c##
abc###e#df###//输入
3
a##
a
a
1
ab##c##
bac
bca
2
abc###e#df###
cbaefd
cbfdea
2
//输出
代码如下
#include<stdio.h>
#include<stdlib.h>
typedef struct tt {
char c;
struct tt *l,* r;
}T;
T* ct(T* r) {
//建树
char c;
scanf_s(" %c", &c);//!!!注意%c前的空格,它会避免读入回车
if (c =='#')
r = NULL;
else {
r = (T*)malloc(sizeof(T));
r->c = c;
r->l=ct(r->l);
r->r=ct(r->r);
}
return r;
}
void in(T *r) {
//中序
if (r == NULL)return;
in(r->l);
printf("%c", r->c);
in(r->r);
}
void post(T *r) {
//后序
if (r == NULL)return;
post(r->l);
post(r->r);
printf("%c", r->c);
}
int lnum(T* r) {
//求叶节点个数
if (r == NULL)return 0;
int num;
int n1 = lnum(r->l);
int n2 = lnum(r-> r);
if (n1 == 0 && n2 == 0)
num = 1;
else num = n1 + n2;
return num;//联想求树高写的递归,真的很巧妙
}
int main() {
int n;
scanf_s("%d", &n);
int i = 0;
while (i++ < n) {
T *tr = NULL;
tr = ct(tr);
in(tr);
printf("\n");
post(tr);
printf("\n");
printf("%d\n",lnum(tr));
}
return 0;
}