```c
//二叉树的建立
typedef struct btree {
char data;
struct btree* lchild;
struct btree* rchild;
}btnode, *bitree;
void visit(char c, int level)
{
printf("%c 在第 %d 层 \n", c, level);
}
//建立二叉树,默认方法用户输入是按照前序遍历的方式输入。
void creat(bitree *T)
{
char c;
scanf("%c", &c);
if (c == ' ')
{
*T = NULL;
}
else {
*T = (btnode *)malloc(sizeof(btnode));
(*T)->data = c;
printf("%c\n", (*T)->data);
creat(&(*T)->lchild);
creat(&(*T)->rchild);
}
// printf("进 入\n");
}
//采用前序遍历的方法
void preorder(btnode *T, int level)
{
if (T)
{
visit(T->data, level);
preorder(T->lchild, level + 1);
preorder(T->rchild, level + 1);
}
}
int main()
{
bitree T;
int level;
level = 1;
T = NULL;
creat(&T);
preorder(T, level);
free(T);
return 0;
}
本次建立二叉树采用的是链式存储的方法,在为creat传参的时候很容易犯错:传值和传址。
如果creat中形参定义为btnode *T,那么T是一个一级指针,类型为btnode*。在main函数中调用creat的时候,creat(T),就相当于传值操作,在内存中会拷贝一份T,然后执行creat中的操作,但是这个操作只在creat中有效,而且修改的是T的拷贝值,没有修改到真正的T,因此函数出来之后T仍然是NULL,这就是在preorder中跳出来的原因。
但是creat(bitree * T),就相当于struct btree** T,相当于T是一个二级指针,我们对二级指针进行解引用就是修改一级指针中存放的值,在main函数中使用从creat操作,传入的是T的地址,这是一个传地址操作,会修改T的值,从而把T带回来。