带指针指针的二叉树递归插入

时间:2014-07-28 06:35:53

标签: c pointers recursion data-structures tree

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);

如果我的理解错误,请纠正我。我是新手。感谢。

3 个答案:

答案 0 :(得分:1)

请记住,在C语句中,通过值传递,这意味着您作为参数传递的表达式的值是复制到函数中。因此,如果更改函数内的参数,则只更改副本,并且调用者将无法看到更改(即更改已丢失)。

要解决该问题,您可以通过传递指针来模拟通过引用传递。如果你想改变一个指针,你就会传递一个指向指针的指针。

如果查看insert函数,当*treeNULL时(即没有节点),您将看到它指向指针。如果你没有将指针传递给指向节点的指针,那就不行了。


愚蠢的例子:

#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。按引用传递=不创建副本,但指向正在传递的值。如果发生了变化,则值将发生变化。

双指针(**)指向单个指针(*)的地址。因此,如果将单个指针传递给函数,则需要使用双指针来更改单个指针的值(地址)。否则,没有变化。