标签(空格分隔): 数据结构与算法
最近在学习二叉树,在创建二叉树的过程中,看到很多资料上都是下面的写法,感到很困惑,首先说一下,下面的写法是正确的。
数据结构定义:
typedef char ElemData;
typedef struct node {
ElemData data;
struct node *left_tree, *right_tree;
}Node ,*Tree;
清除scanf
缓存函数
void safe_clear_scanf_buffer(FILE *fp)
{
int ch;
while ((ch = fgetc(fp)) != EOF && ch != '\n');
}
创建二叉树函数:
void createTree(Tree *T) {
char c;
scanf("%c", &c);
//清除scanf的缓存,保证下次输入一定以想要输入的字符
safe_clear_scanf_buffer(stdin);
if (c == ' ') {
*T = NULL;
}else {
*T = malloc(sizeof(Node));
(*T)->data = c;
createTree(&((*T)->left_tree));
createTree(&((*T)->right_tree));
}
}
第一次看这个东西的时候突然很有困惑,恩,老手就不要见笑了,我这是第一次看,可能是由于C指针还不到家。下面我说一下我疑惑在什么地方。
Tree类型明明已经给是一个指针了,为什么还要用在用一层指针,哈哈哈,分析明白了,突然发现这个问题很白痴,
我的最初想法是为什么不用这种方式创建了呢?(这个函数是错误的)
void createTree2(Tree T) {
char c;
scanf("%c", &c);
//清除scanf的缓存,保证下次输入一定以想要输入的字符
safe_clear_scanf_buffer(stdin);
if (c == ' ') {
T = NULL;
}else{
T = malloc(sizeof(Node));
createTree(T->left_tree);
createTree(T->right_tree);
}
}
我会出现这个疑惑的归根到底是对指针的使用没有加强训练,以后还是要多动手啊。
首先我们咋一看,这个函数好像没问题,但是我们结合main
函数调用的时候就发现问题来了。
int main() {
Tree Tree;
createTree2(Tree);
return 0;
}
分析:
首先我们定义了一个Tree
变量,这个变量本质上就是Node *
类型的,就是指针类型了的,我们调用createTree2
函数,有两个功能,一是为这颗树创建结点内存空间,二是为空间的数据赋值。
先看第一个需求,为结点
创建内存空间
,也就是为指针变量赋值一个内存地址
,就是为Tree
赋值,我们通过函数间接的对Tree
变量赋值,应该对Tree
变量去地址。如果通过createTree2
函数我们发现,实质上传递的是一个NULL
,然后在函数内部,对这个NULL
进行了赋值,由于函数的参数的传递是值传递
,此时赋值操作并没有使主函数中的Tree
发生改变。
第二个需求,我们对数据进行赋值,和上面的原因相同,自创建左右子树的时候也无法对指针进行赋值,因此,满足上面的两个需求,函数的形参必须使用二级指针
才行。
归根到底还是一句话:间接修改一个变量的内容时,使用一级指针, 间接修改一级指针变量的内容时,则需要使用二级指针