Исходный код работает неправильно, если список содержит один узел до добавления нового узла. Давайте назовем этот узел 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;