【问题标题】:Validate the claim that it is better to use pointers to pointers while working with binary trees验证在使用二叉树时使用指向指针的指针更好的说法
【发布时间】:2013-12-19 02:43:24
【问题描述】:

In this video (a section/recitation for an online course called CS50),大约 1h00m00s,学生导师进入指针到指针以及为什么更有效 有用以这种方式在二叉树上实现插入.至少,这是我从争论中得到的。

我以两种方式进行了递归实现。我不明白为什么选项 A 在下面比选项 B 更好...如果我被误解了,也许你可以帮我推理或指出正确的方向?

选项 A(带有指向指针的指针)

bool insert(int value, node* tree)
    {
        node** tmptree = &tree;
        // make sure the tree itself isn't null
        if(*tmptree != NULL)
        {
            if(value == (*tmptree)->value)
            {
                return false;
            }
            else if(value < (*tmptree)->value)
            {
                tmptree = &(*tmptree)->left;
                // we must be at a null leaf!
                if(*tmptree == NULL)
                {
                    // make sure we built a leaf
                    *tmptree = build_node(value);
                    if(*tmptree == NULL)
                    {
                        return false;
                    }
                    return true;
                }
                else
                {
                    return insert(value, *tmptree);
                }
            }
            else
            {
                tmptree = &(*tmptree)->right;
                if(*tmptree == NULL)
                {
                    *tmptree = build_node(value);
                    if(*tmptree == NULL)
                    {
                        return false;
                    }
                    return true;
                }
                else
                {
                    return insert(value, *tmptree);
                }
            }
        }
        return false; // if the tree is null
    }

选项 B(常规 ptrs)

    bool insert(int value, node* tree)
    {
        if(tree != NULL)
        {
            if(value == tree->value)
            {
                return false;
            }
            else if(value < tree->value)
            {
                if(tree->left == NULL)
                {
                    node* tmp = build_node(value);
                    if(tmp != NULL)
                    {
                        tree->left = tmp;
                        return true;
                    }
                    return false;
                }
                else
                {
                    return insert(value, tree->left);
                }
            }
            else
            {
                if(tree->right == NULL)
                {
                    node* tmp = build_node(value);
                    if(tmp != NULL)
                    {
                        tree->right = tmp;
                        return true;
                    }
                    return false;
                }
                else
                {
                    return insert(value, tree->right);
                }
            }
        }
        return false; // if the tree is null
    }

build_node 函数:

    node* build_node(int value)
    {
        node* node = malloc(sizeof( node ));
        if(node == NULL)
            return NULL;
        node->value = value;
        node->left = NULL;
        node->right = NULL;
        return node;
    }

【问题讨论】:

  • 你的第二个实现根本不起作用。
  • 你在哪里看到问题?
  • 当一个值在 C 中作为参数传递时,它会被复制。所以这样做node **tmptree = &amp;tree; 是没有用的,因为它指的是副本,而不是原始树。因此,当您使用修改副本的函数*tmptree = build_node (value); 时,它不会向树中添加任何内容。如果要使用常规指针,则需要以 functional 样式实现。
  • 使用缩进更好!
  • 更准确地说,A 和 B 都是错误的。在这种情况下,指向本地指针的指针是毫无意义的。

标签: c pointers binary-tree cs50


【解决方案1】:

我相信你误解了为什么原始代码中有一个指针。 “选项a”没有任何意义,仅仅为了它而使用指针对指针没有任何好处。

您使用指针到指针的唯一原因是因为您想更改指向的地址并将其返回给调用者。

例如

void func (int** ptr)
{
  *ptr = something;
}

func(&my_ptr);

// is the very thing same as

int* func (int* ptr)
{
  return something;
}

my_ptr = func(my_ptr);

您不能使用第二个版本并在函数内键入ptr = something,因为ptr 是一个局部变量,一旦您离开该函数,它将不复存在。给它赋值不会影响调用方的原始指针。

指针到指针版本的唯一优点是返回的类型可以用于其他用途,例如返回错误代码。

这似乎正是那个视频中的那个人使用它的原因。他的功能看起来像

bool insert (int value, node** tree);

*tree 被分配为指向函数内部的另一个地址,当他到达树枝的末端时,布尔值用作状态码。

【讨论】:

  • 我认为你是完全正确的。我重新观看了我坚持的视频部分,学生传入node** 的原因是如果指向节点指针的指针是NULL,则更改树的组成。这样,如果有人传入&amp;root where node* root = NULL;,则树可以将插入的值作为根node*,这是在二叉树上插入的预期行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2015-07-18
  • 2023-03-20
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多