将节点添加到c中的双循环链表的开头

问题描述 投票:2回答:3

我正在尝试将'n'个节点的数量添加到双循环链接列表的开头这是添加节点的功能:

//the **head is assigned the address of the original head pointer which is being passed from the main function.

void insert(struct node**head,int n){
 while(n-- >0){
    int num;
    //to input the data for the linked list
    scanf("%d",&num);
    struct node* newnode=(struct node*)malloc(sizeof(struct node));
    newnode->data=num;

    if(*head==NULL){
        newnode->next=newnode;
        newnode->prev=newnode;

        *head=newnode;
    }
    else{

        newnode->next=*head;
        newnode->prev=(*head)->prev;

        //to make the previously first node point to the new first node
        newnode->next->prev=newnode;
        //to make the last node point to the new first node
        (*head)->prev->next=newnode;
        *head=newnode;

    }
 }
}

当我执行它时,它没有显示任何输出,但是当我更改时

//to make the last node point to the new first node
            (*head)->prev->next=newnode;

此行到

newnode->prev->next=newnode;

代码正在运行。我无法理解这两个语句之间的区别。

c circular-list
3个回答
1
投票
(*head)->prev->next=newnode;
...
newnode->prev->next=newnode;

我无法理解这两个语句之间的区别。

newnode->prev已正确设置为head之前的节点。相反,由于(*head)->prev,此时的newnode->next->prev=newnode已经被newnode->next=*head更改。因此,(*head)->prev不再指向head之前的节点,而是指向新节点。就是这样。


0
投票

下一个代码假定head定义为:struct node* head;。我只是删除了一些额外的解引用运算符(*)。

它不能直接测试,因为没有提供最低可重复性的示例。

 while(n-- >0){
    int num;
    //to input the data for the linked list
    scanf("%d",&num);
    struct node* newnode=(struct node*)malloc(sizeof(struct node));
    newnode->data=num;

    if(head==NULL){              /*   was: if(*head==NULL){   */
        newnode->next=newnode;
        newnode->prev=newnode;

        head=newnode;{              /*   was: *head=newnode;{   */
    }
    else{

        newnode->next=head;              /*   was: newnode->next=*head;   */
        newnode->prev=(*head)->prev;

        //to make the previously first node point to the new first node
        newnode->next->prev=newnode;
        //to make the last node point to the new first node
        (*head)->prev->next=newnode;
        head=newnode;              /*   was: *head=newnode;   */
    }
 }

0
投票

当列表包含一个节点,然后添加新节点时,原始代码出错。让我们将该节点称为A以供参考。在插入新节点之前,情况如下:

/* List with single node. */
(*head) = &A;
A.next = &A;
A.prev = &A;

让我们调用newnode B指向的节点:

newnode = &B;

当前为newnode的代码如下(带有注释//>):

    newnode->next=*head;         //> B.next=&A;
    newnode->prev=(*head)->prev; //> B.prev=&A;

    //to make the previously first node point to the new first node
    newnode->next->prev=newnode; //> A.prev=&B;
    //to make the last node point to the new first node
    (*head)->prev->next=newnode; //> B.next=&B; !!! want A.next = &B;
    *head=newnode;

以上代码序列之后的情况:

(*head) = &B;
B.next = &B; // !!! want B.next = &A;
B.prev = &A;
A.next = &A; // !!! want A.next = &B;
A.prev = &B;

该列表已损坏,因为更改了错误的链接指针。可以通过使用设置为lastnode的旧值的临时变量(*head)->prev进行修复。更新后的代码如下:

    struct node *lastnode;
    lastnode=(*head)->prev;      //> lastnode=&A;
    newnode->next=*head;         //> B.next=&A;
    newnode->prev=lastnode;      //> B.prev=&A;

    //to make the previously first node point to the new first node
    newnode->next->prev=newnode; //> A.prev=&B;
    //to make the last node point to the new first node
    lastnode->next=newnode;      //> A.next=&B;
    *head=newnode;

更新代码序列后的情况:

(*head) = &B;
B.next = &A;
B.prev = &A;
A.next = &B;
A.prev = &B;
© www.soinside.com 2019 - 2024. All rights reserved.