今天在做数据结构二叉树的实验时,遇到了一个小问题,庆幸发现的早,不然以后工作写大段大段代码时都不知道怎么跪的。是这样的,实验要求按先序创建二叉树,然后要有三种遍历选择,输入0是重建二叉树,输入1是先序输出,输入2是中序,3是后序。因为我对二叉树还不是很熟,先写了下面的代码试试行不行,结果ok。
typedef struct binode{
char data;
struct binode*lchild, *rchild;
}binode,*bitree;
Status createbitree(bitree *t) //先序创建二叉树
{
char ch;
ch = getchar();
if (ch == '#')
*t = NULL; //表示某节点已经结束
else {
(*t) = (bitree)malloc(sizeof(binode)); //分配空间
(*t)->data = ch; // 生成根结点
createbitree(&(*t)->lchild); // 构造左子树
createbitree(&(*t)->rchild); // 构造右子树
}
if (!t)
return error;
return ok;
}
void preorder(bitree t){//先序
if (t){
printf("%2c", t->data);
preorder(t->lchild);
preorder(t->rchild);
}
}
int main(){
bitree t = null;
printf("\ncreate a bitree\n");
createbitree(&t);
printf("\nthe preorder is:\n");
preorder(t);
}
那就接着干,既然是固定的几个输入选择,我自然的想到了定义一个整型变量用switch,嗯,就这样。就改成下面这样。
int main(){
bitree t = null;
int choose;
printf("输入0,重构二叉树,输入1,先序输出,输入2,终须输出,输入3,后续输出!请输入:\n");
scanf("%d", &choose);
while (choose+1){
switch (choose)
{
case 0:printf("create a bitree\n");
createbitree(&t);
break;
case 1:printf("\nthe preorder is:\n");
preorder(t);
break;
case 2:printf("\nthe midorder is:\n");
midorder(t);
break;
case 3:printf("\nthe lasorder is:\n");
lasorder(t);
break;
default:
break;
}
printf("输入0,重构二叉树,输入1,先序输出,输入2,终须输出,输入3,后续输出!请输入:\n");
scanf("%d", &choose);
}
}
感觉应该没错的样子,结果确实是没报错,能跑,可就是输入0后,输入二叉树的元素后就是停在那,按理应该会显示菜单啊,可怎么还是要继续输入呢,表示程序应该是困在了createbitree函数里了,但函数是没问题的才对,前面还简单的用过了,那怎么回事,在乱输入了很多遍,其实也不是胡乱输,我发现在正常输入树的元素后再多加一个井号,好像就可以了,这是什么情况,于是我在创建函数里的第一行加了个输出,结果菜单后我输入0,加的输出会出来两次,我在原来的那个程序里却只有一次,真是悲剧,函数明明是一样的啊,这会我才把目光看到主函数的switch结构来,但看不出有啥问题。。。后来不知乍得,觉得会不会是对菜单的选择输入对后面产生了影响,灵机一动,在case0后加了个getchar();这下子还真正常了。根据前面过程,我认为也许是scanf函数并没在读了数之后就消除或者将读入起点后挪一位,导致createbitree函数里的getchar始终多读了一位,所以问题就来了。看来这个坑真的很阴险,可能我的观点不对,希望有高人前辈指正。就在我写这篇博客时,我又在尝试了许多不同的输入,结果挺奇怪,或许真的不是这么简单。求赐教!