【问题标题】:binary tree recursive insertion with pointer to pointer带有指针的二叉树递归插入
【发布时间】:2014-09-19 07:25:46
【问题描述】:
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 pointers recursion data-structures tree


【解决方案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 =“富” s2 = "来自 func2 的你好"

【讨论】:

  • 如果我们将指针传递给头部,即节点*树,我们可以检查空指针作为树!= NULL,不是吗??
  • @CodeWithPride 问题不在于检查NULL,而是assignment
  • @CodeWithPride 我在答案中添加了一个小而简单的示例来显示差异。
  • 感谢您的示例.. 现在清楚了.. 非常感谢 :)
【解决方案2】:

这是因为 tree 可以为空 (NULL)。在这种情况下,您可以设置外部指针,使其指向新的根。

node *root = NULL;
insert(root, 10);

【讨论】:

    【解决方案3】:

    传递给函数的两种类型:

    1。按值传递 = 创建值的副本。一旦函数终止,对值的任何更改都将丢失。

    2。通过引用传递 = 不会创建副本,而是指向正在传递的值。如果发生变化,那么值就会发生变化。

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

    【讨论】:

      猜你喜欢
      • 2012-11-16
      • 2014-12-03
      • 2020-07-24
      • 2015-09-19
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      相关资源
      最近更新 更多