在C语言中实现的链表中使用单指针与双指针

在C语言中实现的链表中使用单指针与双指针,c,pointers,linked-list,double-pointer,C,Pointers,Linked List,Double Pointer,我编写了以下代码,用于在链表末尾添加元素: struct node{ int info; struct node* link; }; void append ( struct node **q, int num ) { struct node *temp, *r ; if ( *q == NULL ) // if the list is empty, create first node { temp = (struct node*) malloc (

我编写了以下代码,用于在链表末尾添加元素:

struct node{
    int info;
    struct node* link;
};

void append ( struct node **q, int num )  
{

struct node *temp, *r ;

if ( *q == NULL )       // if the list is empty, create first node
{
    temp = (struct node*) malloc ( sizeof ( struct node ) ) ;
    temp -> info = num ;
    temp -> link = NULL ;
    *q = temp ;        
}
else{
    temp = *q ;         

    /* go to last node */
    while ( temp -> link != NULL )
        temp = temp -> link ;

    /* add node at the end */
    r = (struct node *)malloc ( sizeof ( struct node ) ) ;
    r -> info = num ;
    r -> link = NULL ;
    temp -> link = r ;
}
}
我像这样调用append函数:
追加(&list,10)其中
list
是指向链接列表的指针

这段代码可以工作,但是如果我在append函数中使用单指针(使用*q而不是**q),并进行相应的更改(如下所述,以及在调用它时),它就不工作了。下面的代码有什么问题

void append ( struct node *q, int num )  
{

struct node *temp, *r ;

if ( q == NULL )       // if the list is empty, create first node
{
    temp = (struct node*) malloc ( sizeof ( struct node ) ) ;
    temp -> info = num ;
    temp -> link = NULL ;
    q = temp ;        
}
else{
    temp = q ;         

    /* go to last node */
    while ( temp -> link != NULL )
        temp = temp -> link ;

    /* add node at the end */
    r = (struct node *)malloc ( sizeof ( struct node ) ) ;
    r -> info = num ;
    r -> link = NULL ;
    temp -> link = r ;
}
}

因为在第二个示例中,
q
是调用方传入的指针的副本。调用方的原始指针永远不会被修改。

在您的第一个代码段中(这是正确的),您做的太多了

void append ( struct node **q, int num )  
{

struct node *new ;

    /* go to last node */
    for ( ; *q; q = &(*q)->link ) {;}

    /* add node at the end */
    new = malloc ( sizeof *new );
    if (!new) { barf_now(); return; }

    new->info = num ;
    new->link = NULL ;
    *q = new; ;
    }
}
其基本思想是:您希望附加到列表的尾部;您需要:

  • 找到第一个空指针
  • 将其值设置为新指针的值

“空列表”的情况并不特殊,它只是意味着您可以在零步中找到空指针。以这种方式进行编码没有特殊情况,如果(…)。。。else…
construct.

但是
list
是指向节点的指针。因此,它存储一个地址。所以,当我调用
append(列表,10)我正在传递地址,因此,这不应该更改原始的链表。@Jatin:对于标记为“如果列表为空,请创建第一个节点”的代码部分,不应该更改。因此,假设列表中至少有1个元素,则第二个代码将工作,是吗?还有@Oli,你能详细说明一下你最后的评论吗?@Jatin:if
部分修改了
q
的值,但这不会反映在调用方传入的值中(因为它是一个副本)。但是,其他的< /Cult>节不这样做,所以这部分可能是OK。因为C和C++是紧密相关的,我假设有C++知识的人可以帮助我。顺便说一下,这是一个不好的方法,将一个元素追加到列表中,因为运行时随着元素的数量线性增加。传统的方法是维护一个指向列表两端的指针,这样可以在固定时间内完成追加。