1

I found this code online for reversing a linked list using only 2 pointers using xor operation :

void reverse(struct Node** head_ref) 
{ 
    struct Node* prev = NULL; 
    struct Node* current = *head_ref; 

    // at last prev points to new head 
    while (current != NULL) { 
        current = (struct Node*)((ut)prev ^ (ut)current ^ (ut)(current->next) ^ (ut)(current->next = prev) ^ (ut)(prev = current)); 
    } 

    *head_ref = prev; 
} 

Can you please explain how this code works ?

10
  • What is ut? Does it work on a 64-bit system or only on a 32-bit system? Commented May 16, 2020 at 6:47
  • 1
    This looks more like C to me. Commented May 16, 2020 at 7:04
  • 2
    That has undefined behaviour due to the unsequenced pairs prev/prev = current, and current->next/current->next = prev. geeksforgeeks is not a reliable source of knowledge. Commented May 16, 2020 at 7:12
  • 1
    they had included <bits/stdc++.h> then you can probably safely ignore them and everything they write. Commented May 16, 2020 at 10:14
  • 2
    There's nothing to explain. As I said earlier, that code has undefined behaviour, so anything can happen. Don't try to learn from geeksforgeeks, it's not good. Commented May 16, 2020 at 12:40

1 Answer 1

3

Have you read this: Iteratively Reverse a linked list using only 2 pointers?

   while (current != NULL) { 
        // This expression evaluates from left to right 
        // current->next = prev, changes the link fron 
        // next to prev node 
        // prev = current, moves prev to current node for 
        // next reversal of node 
        // This example of list will clear it more 1->2->3->4 
        // initially prev = 1, current = 2 
        // Final expression will be current = 1^2^3^2^1, 
        // as we know that bitwise XOR of two same 
        // numbers will always be 0 i.e; 1^1 = 2^2 = 0 
        // After the evaluation of expression current = 3 that 
        // means it has been moved by one node from its 
        // previous position 
        current = (struct Node*)((ut)prev ^ (ut)current ^ (ut)(current->next) ^ (ut)(current->next = prev) ^ (ut)(prev = current)); 
    } 
Sign up to request clarification or add additional context in comments.

11 Comments

It means the previous node has 1 as value and the current one is 2, they have ascending order. This is the key: (ut)(current->next = prev) ^ (ut)(prev = current), is storing addresses (uintptr_t is an integer type capable of holding a pointer) in a temporary using xor operations while assigning the previous node (stored in the previous iteration). Is obfuscated code and add nothing to the conventional way of doing it: geeksforgeeks.org/reverse-a-linked-list/?ref=rp
The first iteration swaps the address of NULL (0) with the address of the first node: 0 ^ 1 (xoring any value with 0 is a NOOP), then 1 ^ 2, then 2 ^ 3 and so on ...
Yes, ^ is swapping addresses not values
See the comment of @Molbdnilo: That has undefined behaviour due to the unsequenced pairs prev/prev = current, and current->next/current->next = prev this is UB, you can not tell the order, do not use this code.
Thank you ! Then, does that mean reversing linked list with 2 pointers is not possible (other than this code using xor) ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.