2

我对 C 中的符号链表有疑问。我创建了一个链表,代码如下所示:

#include <stdio.h>
#include <stdlib.h>
struct node 
{
    int data;
    struct node* next;
};

struct node *mknode(int data)
{
    struct node* np=malloc(sizeof(struct node));
    np->data=data;
    np->next=NULL;
    return np;
}

struct node * insert (struct node* list,int data)
{
    struct node *np;
    struct node*curr=list;
    struct node* prev=NULL;
    np=mknode(data);
    for(;curr &&data<curr->data;curr=curr->next )
        prev=curr;


    np->next=curr;
    if(prev)
        prev->next=np;
    else
        list=np;
    return list;
}


int main()
{
    struct node* head;
    head=malloc(sizeof(struct node));
    head=insert(head,7);
    head=insert(head,2);
    head=insert(head,4);
    printf("%d",head->data);
    printf("%d",head->next->data);
    printf("%d",head->next->next->data);
    return 0;
}

但是,当我在互联网上搜索时,我意识到,双指针用于创建链表而不是普通指针。我的意思是struct node **list,,不是struct node * list。我想知道为什么 ?哪一个是正确的,如果它们都是正确的,它们之间有什么区别,我将我的实现与我在这里编写的示例 main 一起使用,它工作正常但我不知道为什么要使用指向指针的指针?提前致谢。

4

5 回答 5

3

有些人使用指向指针的指针的原因是可以在不返回新指针的情况下更新节点。在您的示例中,如果您想更改头指针,则必须创建一个新指针,然后使头等于该指针。使用双指针,您只需释放第二个指针指向的空间,然后将第二个指针更新为新的数据结构,从而保留原来的头指针

我只是在我的实现中使用单指针。

于 2013-08-06T15:12:18.227 回答
1

给定

struct node { int x; };
struct node **pplist;
struct node *plist;

pplist是指向 a 的指针的指针struct node,而plist是指向 a 的指针struct node。要更改 x,您需要编写

*pplist->x = 3;
plist->x = 4;

如果您希望同一个变量指向不同的列表,或者如果您想将指针传递给具有更改该指针的副作用的函数,则可以使用指向指针的指针。

于 2013-08-06T15:18:01.013 回答
1

阅读此处,通过这种方式,您可以更改元素而无需创建新元素。

在链表中添加节点时使用双指针的原因是什么?

于 2013-08-06T15:14:09.247 回答
0

这对我来说看起来非常好。

所有的指针都是指向某个地方的内存地址。双指针只是指向另一个指向某些数据的内存地址的内存地址。

也许您可以发布您看到的地方node **list,我们可以更好地解释它,但现在,您的代码看起来不错。

于 2013-08-06T15:10:40.570 回答
0

如果您调用“head = NULL; insert(&head, data);”,这有点自然。然后 head 指向第一个元素。所有打算改变内容的函数都应该被间接调用。但是:这是编码约定的问题。有人喜欢热的,有人喜欢冷的。head=insert(head, data); 的问题 也就是说,当您忘记“head =”时,该头部无法使用

于 2013-08-06T15:12:57.620 回答