In swapNode
, A
и B
изначально NULL
. L oop, который ищет два совпадающих узла, завершается рано, когда обнаруживается любой из узлов:
if (A || B)
break;
Не более одного из A
и B
будет ненулевым, если l oop завершается, поэтому хотя бы один из A
и B
будет равен NULL. Это заставляет функцию возвращать false
:
if (!A || !B)
return false;
Чтобы избежать этого, вы должны изменить l oop на разрыв, когда оба A
и B
не равны NULL:
if (A && B)
break;
Кроме того, l oop проверяет только count - 1
элементы списка, поэтому игнорирует последний элемент:
for (int i = 0; i < listNode->count - 1; i++)
Чтобы проверить все элементы, вам необходимо изменить это to:
for (int i = 0; i < listNode->count; i++)
В качестве альтернативы, вы можете проигнорировать listNode->count
и проверить вместо него указатель temp
:
while (temp != NULL)
Это будет работать, потому что temp
инициализируется в listNode->head
, который будет NULL
для пустого списка, а для непустого списка, элемент next
последнего элемента в списке равен NULL
, поэтому temp = temp->next;
установит temp
в NULL
когда проверен последний элемент.
В swapNode
есть другие проблемы, связанные с фактической заменой узлов после того, как они были найдены. Исходный код для этого выглядит совершенно неверно:
*temp = *A;
*A = *B;
*B = *temp;
Указатель temp
будет либо NULL
, либо будет указывать на узел после узлов A
и B
.
if (A->prev)
A->prev->next = A;
if (A->next)
A->next->prev = A;
if (A->prev)
A->prev->next = A;
if (A->next)
A->next->prev = A;
Код не изменяется listNode->head
или listNode->tail
, когда A
или B
находится в начале или конце списка.
free(temp);
Почему он освобождается temp
здесь, когда все функции, которые предполагается выполнять, это обмен узлами?
Код для замены узлов A
и B
должен иметь возможность иметь дело ни с одним, ни с одним из обоих узлов, находящихся на конец (и) списка, причем A
и B
являются соседними узлами в любом порядке. Вот последовательность для обработки всего этого:
/* update list head pointer */
if (listNode->head == A)
listNode->head = B;
else if (listNode->head == B)
listNode->head = A;
/* update list tail pointer */
if (listNode->tail == A)
listNode->tail = B;
else if (listNode->tail == B)
listNode->tail = A;
/* update ->prev->next pointers */
if (A->prev != NULL && A->prev != B)
A->prev->next = B;
if (B->prev != NULL && B->prev != A)
B->prev->next = A;
/* update ->next->prev pointers */
if (A->next != NULL && A->next != B)
A->next->prev = B;
if (B->next != NULL && B->next != A)
B->next->prev = A;
/* update A->prev and B->prev pointers */
if (A->prev == B)
{
A->prev = B->prev;
B->prev = A;
}
else if (B->prev == A)
{
B->prev = A->prev;
A->prev = B;
}
else
{
temp = A->prev;
A->prev = B->prev;
B->prev = temp;
}
/* update A->next and B->next pointers */
if (A->next == B)
{
A->next = B->next;
B->next = A;
}
else if (B->next == A)
{
B->next = A->next;
A->next = B;
}
else
{
temp = A->next;
A->next = B->next;
B->next = temp;
}