[英]binary tree recursive insertion with pointer to pointer
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
指针来表示二叉树的头。 我在许多教程和网站上都遇到了相同的方法。 我想知道为什么每个人都坚持使用指针指向指针,为什么不只是使用“ node * tree”。 我认为即使指向树头的指针也能很好地完成工作,而仅使用指向树头的指针,递归调用将如下所示(如果我错了,请纠正我):
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);
如果我的理解是错误的,请纠正我。 我是新手。 谢谢。
请记住,在C中,参数是通过value传递的 ,这意味着将作为参数传递的表达式的值复制到函数中。 因此,如果您在函数内更改参数,则仅更改副本,并且该更改将对调用者不可见(即更改丢失)。
为了克服该问题,您可以通过传递指针来模拟按引用传递。 如果要更改指针,则必须将指针传递给该指针。
如果查看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"
这是因为tree
可以为空( NULL
)。 在这种情况下,您可以设置外部指针使其指向新的根。
node *root = NULL;
insert(root, 10);
传递给函数的两种类型:
1.按值传递=创建值的副本。 函数终止后,对该值的任何更改都将丢失。
2.通过引用传递=不会创建副本,但指向要传递的值。 如果发生更改,则值将更改。
双指针(**)指向单个指针(*)的地址。 因此,如果将单指针传递给函数,则需要使用双指针来更改单指针的值(地址)。 否则,没有任何变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.