Wyobraź sobie, że funkcja jest wywołana w takiej sytuacji:
// list1 = linked_list(1 -> 2 -> 3 -> 4)
// list2 = linked_list(5 -> 6 -> 7 -> 8)
swap_node(&list1, 0, &list2, 0);
// expected outcome
// list1 = linked_list(5 -> 2 -> 3 -> 4)
// list2 = linked_list(1 -> 6 -> 7 -> 8)
Czy dałoby się wykonać ta operację, jeśli miałbyś tylko pojedynczy wskaźnik?
BTW nie ufaj autorowi tego zadania, bo jest kilka wskazówek pokazujących, że słabo się zna na C
, a robił za dużo kursów C++
i ma problem z rozróżnieniem tych języków programowania.
Ok teraz zajarzyłem, że nie łapiesz po co tu jest lista. W końcu można zwabić zamianę na value
i gotowe.
Generalnie założenie jest takie, że value
trzymane przez listę jest czymś dużym i ciężkim do kopiowania.
Struktura listy ma zapobiec jawnemu kopiowaniu value
, a przestawianie elementów ma się odbywać przez kopiowanie wskaźników next
listy.
W zadaniu dla uproszczenia zastosowano typ int
dla value
(bo typ trzymanych danych jest mało znaczącym detalem, dla problemu), przez co stosowanie listy traci sens i ukrywa sens zadania.
Podwójny wskaźnik, ułatwia takie rozwiązanie, że value
nie jest kopiowane, a elementy listy są przestawiane, przez podmianę wartości next
.
Przykład mojego rozwiązania (przeszło):
LinkedList* nodePointerAtIndex(LinkedList* l, int index)
{
while (index && *l) {
l = &(*l)->next;
--index;
}
return l;
}
void nodeSwapPointers(LinkedList *a, LinkedList *b)
{
LinkedList tmp = *a;
*a = *b;
*b = tmp;
}
int swapNodes(LinkedList *listPointer1, unsigned int index1, LinkedList *listPointer2, unsigned int index2)
{
listPointer1 = nodePointerAtIndex(listPointer1, index1);
listPointer2 = nodePointerAtIndex(listPointer2, index2);
if (!*listPointer1 || !*listPointer2)
{
return 0;
}
nodeSwapPointers(&(*listPointer1)->next, &(*listPointer2)->next);
nodeSwapPointers(listPointer1, listPointer2);
return 1;
}
https://www.codewars.com/kata/reviews/58ef7bbafbf6efcc630005df/groups/65773e9f01c98d0001b06004