I adapted @dkamins' solution, in a way. Instead of taking in a pointer to a pointer, I return the new head
. I also beefed it up.
struct Node
{
struct Node *next;
int data;
};
typedef struct Node * NodePtr;
NodePtr swapEveryTwo(NodePtr head)
{
NodePtr newHead = (head && head->next) ? head->next : head;
NodePtr n = head;
while(n && n->next)
{
NodePtr tmp = n; // save (1)
n = n->next; // (1) = (2)
tmp->next = n->next; // point to the 3rd item
n->next = tmp; // (2) = saved (1)
n = tmp->next; // move to item 3
// important if there will be further swaps
if(n && n->next) tmp->next = n->next;
}
// return the new head
return newHead;
}
Basically, the new head of the list is either the current head if NULL
or length 1, or the 2nd element.
In the swap loop, tmp
will eventually become the 2nd element, but initially it is the first. We need it therefore to point to the 3rd element, which is the purpose of tmp->next = n->next;
. I don't use a for
loop because if we did, it is less intuitive - the reevaluation expression would only appear to be jumping by 1 node per iteration. At the end of the while
loop, n = tmp->next;
makes intuitive sense - we are pointing it to the element after tmp
, the 2nd element.
The most important part is the last line. Because we are doing this in a forward direction, we have to remember that the previous iteration's 2nd element is almost certainly going to be pointing to the current iteration's eventual 4th element, because this iteration will swap 3 and 4. So at the end of the iteration, if we realize we are going to swap again next iteration, we quietly point the 2nd element to the current 4th element, knowing that next iteration it will be the 3rd element and all is right in the world.
For example, if the list is 2 -> 7 -> 3 -> 5
:
n = 2
tmp = 2
n = 7
tmp->next = 3 (2 -> 3)
n->next = 2 (7 -> 2)
n = 3
7 -> 2 -> 3 -> 5
but then there will be swaps, so the last statement says
7 -> 2 -> 5 3?
This is ok because n = 3, so we haven't lost that node. Next iteration:
n = 3
tmp = 3
n = 5
tmp->next = NULL (3 -> NULL)
n->next = 3 (5 -> 3)
n = NULL
Leading to the final 7 -> 2 -> 5 -> 3
answer.