最终代码:
#include <stdio.h>
#include <malloc.h>
typedef struct TNode
{
char data;
TNode* lchild;
TNode* rchild;
}TNode;
void BuildTree(TNode* &T)//先序递归建立二叉树
{
char ch;
scanf("%c",&ch);
if(ch=='#')
{
T=NULL;
}
else
{
T=(TNode*)malloc(sizeof(TNode));
T->data=ch;
BuildTree(T->lchild);
BuildTree(T->rchild);
}
}
int PreOrder(TNode* &T)
{
if(T!=NULL)
{
printf("%c",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
int main()
{
TNode *T;
BuildTree(T);
PreOrder(T);
return 0;
}
char ch;
scanf("%c",ch);
程序刚开始就得把全部字符序列输入进去,比如“AB##C##”,而不是每次递归的时候输入一个。进入递归一次,就scan一个字符。因为scanf("%c",&ch)每次只会读入一个字符。还有记得在ch前加“&”取地址符。
while(c!='#')
{
}
还有,并不是用while。
if(c=='#')
return 0;
不能就这么简单地return 0,想想你忘了什么?T=NULL啊。
if(c=='#')
{
T=NULL;//把这个忘了就死循环了
return 0;
}
if(c=='#')
{
T=NULL;//把这个忘了就死循环了
return 0;//这里用不用return 0其实有没有关系?
}
if(c!='#')
{
T=(TNode*)malloc(sizeof(TNode));
T->data=c;
BuildTree(T->lchild);
BuildTree(T->rchild);
}
if(c=='#')
{
T=NULL;
}
else
{
T=(TNode*)malloc(sizeof(TNode));
T->data=c;
BuildTree(T->lchild);
BuildTree(T->rchild);
}
搞清楚递归的时候,哪一步执行完回到哪一步。
T=(TNode*)malloc(sizeof(TNode));//1号
这里不是:
TNode *T=(TNode*)malloc(sizeof(TNode));//2号
如果是2号,那就相当于重新申请了一个结点?本来递归传参的时候,BuildTree(T->lchild)就相当于声明进入递归函数中的T了吧。如果是2号,那原有的T->lchild就改变了,变成了新声明的T了。我是这样理解的。假如说传进去的T->lchild是001,新声明的T就是002,是不一样的。
主函数中:
TNode* T=(TNode*)malloc(sizeof(TNode));
T->lchild=NULL;
T->rchild=NULL;
//我感觉这三句是多余的,因为在建树里会动态申请结点
BuildTree_1(T);
直接改成:
TNode* T;
BuildTree_1(T);
就OK了吧。