void insert(node ** tree, int val)
{
node *temp = NULL;
if(!(*tree))
{
temp = (node *)malloc(sizeof(node));
temp->left = temp->right = NULL;
temp->data = val;
*tree = temp;
return;
}
if(val < (*tree)->data)
{
insert(&(*tree)->left, val);
}
else if(val > (*tree)->data)
{
insert(&(*tree)->right, val);
}
}
此函数使用指针node ** tree
的指针来表示二叉树的头部。我在许多教程和网站上遇到了相同的方法。我想知道为什么每个人都坚持使用指针指针,为什么不只是'节点*树&#39;。我认为即使指向树头的指针也可以正常工作,只使用指向树头的指针,递归调用如下(如果我错了请纠正我):
insert(tree->left, val); // assuming definisiton as void insert(node *tree, int val);
或
insert(tree->right, val); // assuming definisiton as void insert(node *tree, int val);
如果我的理解错误,请纠正我。我是新手。感谢。
答案 0 :(得分:1)
请记住,在C语句中,通过值传递,这意味着您作为参数传递的表达式的值是复制到函数中。因此,如果更改函数内的参数,则只更改副本,并且调用者将无法看到更改(即更改已丢失)。
要解决该问题,您可以通过传递指针来模拟通过引用传递。如果你想改变一个指针,你就会传递一个指向指针的指针。
如果查看insert
函数,当*tree
为NULL
时(即没有节点),您将看到它指向指针。如果你没有将指针传递给指向节点的指针,那就不行了。
愚蠢的例子:
#include <stdio.h>
void func1(const char *s)
{
s = "hello from func1";
}
void func2(const char **s)
{
*s = "hello from func2";
}
int main(void)
{
const char *s1 = "foo";
const char *s2 = "bar";
func1(s1); /* Passing pointer by value */
func2(&s2); /* Passing pointer by "reference" */
printf("s1 = \"%s\"\n", s1);
printf("s2 = \"%s\"\n", s2);
}
上面的小例子程序将打印
s1 = "foo" s2 = "hello from func2"
答案 1 :(得分:0)
那是因为tree
可以为空(NULL
)。在这种情况下,您可以设置外部指针使其指向新的根。
node *root = NULL;
insert(root, 10);
答案 2 :(得分:0)
传递给函数的两种类型:
1。 Pass by value =创建值的副本。一旦函数终止,对值的任何更改都将丢失。
2。按引用传递=不创建副本,但指向正在传递的值。如果发生了变化,则值将发生变化。
双指针(**)指向单个指针(*)的地址。因此,如果将单个指针传递给函数,则需要使用双指针来更改单个指针的值(地址)。否则,没有变化。