链表头双指针传递

发布于 2024-09-11 04:53:37 字数 748 浏览 7 评论 0原文

我在一些书/教程中看到过这一点。

当您将(链表的)头指针传递给函数时,您需要将其作为双指针传递。

例如: // 这是反转链表,其中头指向第一个节点。

void nReverse(digit **head)
{
    digit *prev=NULL;
    digit *curr=*head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    *head=prev;
    return;
}

这很好用。

当我使用单指针时它也有效,例如

void nReverse(digit *head)
{
    digit *prev=NULL;
    digit *curr=head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    head=prev;
    return;
}

我尝试使用头指针打印列表。这两个功能都运行良好。

我错过了什么吗?

谢谢,

I have seen this in some book/ tutorial.

When you pass in the head pointer (of linked list) into a function, you need to pass it as a double pointer.

For eg:
// This is to reverse a linked list where head points to first node.

void nReverse(digit **head)
{
    digit *prev=NULL;
    digit *curr=*head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    *head=prev;
    return;
}

This works fine.

It also works when I use single pointer like,

void nReverse(digit *head)
{
    digit *prev=NULL;
    digit *curr=head;
    digit *next;

    while(curr!=NULL)
    {
        next=curr->next;
        curr->next=prev;
        prev=curr;
        curr=next;
    }
    head=prev;
    return;
}

I tried printing the list by using the head pointer. Both the functions work fine.

Am I missing something ?

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

橘和柠 2024-09-18 04:53:37

这是非常类似 C 的代码,而不是 C++。

基本上,当某些内容按值传递时,函数会对数据的副本进行操作:

void foo(int i)
{
    i = 5; // copy is set to 5
}

int x = 7;
foo(x);
// x is still 7

在 C 中,您可以传递一个指向变量的指针,并且可以以这种方式更改它:

void foo(int* i)
{
    *i = 5; // whatever i points to is set to 5
}

int x = 7;
foo(&x);
// x is 5

对于您来说,而不是 int code> 这是一个数字*。 (产生指向指针的指针。)


在 C++ 中,引入了引用。引用是另一个对象的别名。所以你会做这样的事情:

void foo(int& i) // i is an alias to another value
{
    i = 5; // x is set to 5
}

int x = 7;
foo(x); // pass x as alias, not address of x.
// x is 5

引用通常是首选,因为它强制你实际引用一个对象,并简化调用和操作代码。

当然,在 C++ 中,您不会自己实现列表,而是使用 std::list

This is very C-like code, not C++.

Basically, when something is passed by-value the function operates on a copy of the data:

void foo(int i)
{
    i = 5; // copy is set to 5
}

int x = 7;
foo(x);
// x is still 7

In C, you instead pass a pointer to the variable, and can change it that way:

void foo(int* i)
{
    *i = 5; // whatever i points to is set to 5
}

int x = 7;
foo(&x);
// x is 5

For you, instead of an int it's a digit*. (Resulting in a pointer to pointer.)


In C++, references were introduced. A reference is an alias to another object. So you'd do something like this:

void foo(int& i) // i is an alias to another value
{
    i = 5; // x is set to 5
}

int x = 7;
foo(x); // pass x as alias, not address of x.
// x is 5

A reference is generally preferred, since it enforces that you actually refer to an object, and simplifies both calling and operating code.

Of course in C++ you wouldn't implement a list yourself, you'd use std::list.

习惯成性 2024-09-18 04:53:37

最后一个 head=prev; 不会更改第二个示例中传递的指针的值。对于此功能而言,该行是否是必需的取决于您。但有一个区别。

您如何测试它“工作正常”?您是否能够迭代列表并打印出节点的值并看到它们实际上已被反转?第一个函数(大概被称为 nReverse(&list); changes list 指向的内容,第二个函数则不会(所以对于第二个函数你怎么知道哪个节点是列表的开头,毕竟它刚刚被更改......)。

That last head=prev; does not change the passed pointer's value in the second example. Whether or not that line is necessary for the purposes of this function is up to you. But there is a difference.

How did you test that it "worked fine"? Were you able to iterate the list and print out the node's values and see that they had in fact been reversed? The first function (presumably called like nReverse(&list); changes what list points to, the second do not (so for the second how do you know which node is the beginning of the list, after all it was just changed...).

病毒体 2024-09-18 04:53:37

在第一个示例中,您传入的内容仍然指向列表的“开头”。

在第二个示例中,它指向列表的末尾(这是您开始时的开头,但后来已移动)。

In the first example, what you passed in still points to the "beginning" of the list.

In the second example, it points to the end of the list (which was the beginning when you started, but has since moved).

救星 2024-09-18 04:53:37

双重间接寻址的原因是 nReverse 可以修改调用者的指针,因为在反转列表之后,列表的头现在是一个不同的节点。

在第二个版本中,您正在修改函数本地的 head 副本,因此调用者仍然拥有对旧头节点(现在是尾部)的引用。

The reason for the double indirection is so nReverse can modify the caller's pointer, since after reversing the list, the head of the list is now a different node.

In the second version, you are modifying the copy of head that is local to the function, so the caller still has a reference to the old head node, which is now the tail.

三五鸿雁 2024-09-18 04:53:37

使用双指针传递(第一个示例)的原因是您想要更改列表的头部。由于您要反转列表,因此在完成反转后,头应该指向列表的最后一个元素。

digit* list; 
// initialize list
nReverse(&list); 
// now list is pointing to the last element of the chain (and not the first)

如果不使用双指针,那么 list 仍将指向原来的第一个元素,而 next 现在指向 NULL,因为它是反转后的最后一个元素。所以你失去了所有其他元素。

The reason for having double pointer passing (the first example) is that you want to change the head of the list. Since you are reversing the list, the head should point to the last element of the list after you have done the reversing.

digit* list; 
// initialize list
nReverse(&list); 
// now list is pointing to the last element of the chain (and not the first)

If you don't use double pointers, then list will still point to the original first element which next now points to NULL because its the last element after the reversing. So you loose all your other elements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文