How the double pointer is actually working in reverse of linked list?

147 Views Asked by At

I had done the reverse of linked list using recursion, but how the pointer actually working a bit confused. If I swap statements 1 and 2 in the below code the program will not run Why? Because I assume (*head)->next = nullptr will set *temp = nullptr so there is no meaning of (*temp)->next = *head, but if this true then in the below code even after statement 1 (*head)->next is set to nullptr so it should set the *temp equals to nullptr and according to that it should not reverse the linked list but actually the code reverse the linked list How?

void push(struct node*& tail, int v)
{
    struct node* newNode = new node;
    newNode->data = v;
    newNode->next = tail;

    tail = newNode;
}

void reverse_ll3(struct node* *rootAddress, struct node* *head, struct node* *temp)
{

    if(!(*temp))
    {
        *rootAddress = *head;
        return;
    }
    reverse_ll3(rootAddress, &((*head)->next), &((*temp)->next));
    
    (*temp)->next = *head; // --------------1
    (*head)->next = nullptr; // --------------2
}

int main()
{
struct node* head = NULL;
struct node* curr;

    push(head, 60);
    push(head, 50);
    push(head, 40);
    push(head, 30);
    push(head, 20);
    push(head, 10);
    
    print_list(head);
    cout << endl;
    
    curr = head;
    reverse_ll3(&head,&curr,&(curr->next));
    
    print_list(head);
    cout << endl;
    
    return 0;

}
1

There are 1 best solutions below

2
pawan097 On

Edited:
Initially, the linked list in main function is:

10|e0 -> 20|d0 -> 30|c0 -> 40|b0 -> 50|a0 -> 60|q0 -> null 
-----    -----    -----    -----    -----    -----    -----
x0       e0       d0       c0       b0       a0       q0

where e0,d0...q0 are next node address

Let x0,e0,d0,...q0 are stored in following address:
e8, f4, e4, d4, c4, b4, a4 i.e

x0  e0  d0  c0  b0  a0  q0
--  --  --  --  --  --  --
e8  f4  e4  d4  c4  b4  a4

Let curr address be e10, so by curr = head, e10 also contain x0

I am passing the e8(&head), e10(&curr), f4(&(curr->next)) to reverse_ll3

when temp = a4 then (!(*a4)) => (!(q0)) is true (q0 is nullptr) will execute the if condition rootAddress contain e8, head contain b4 *rootAddress = *head; i.e *e8 = *b4 => *b4 is a0
e8 now contain a0 contents i.e 60|q0

now recursion will unwind
1st unwind
(*temp)->next = *head here temp contains b4, head contains c4
*b4 = a0, *c4 = b0
(*b4)->next = *c4* is a0->next = b0
a0->next is q0 which is stored in a4 so a4 contents q0 will be replaced by b0 i.e a0 now contains 60|b0 and a4 contains b0
(*head)->next = nullptr
(*c4)->next = b0->next = nullptr, so now a0 will be replaced by nullptr i.e b0 now contains 50|null and b4 contains a0

2nd unwind
here temp contains c4, head contains d4
(*c4)->next = (*d4)
(b0)->next = c0
Similarly a0 will be replaced by c0 i.e now b0 contains 50|c0 and b4 contains c0
Note: Since a4 contains b0(previously b0 contains 50|null, now null is replaced by c0) and b0 contains 50|c0 this implicitly creates link from a0(60|b0) to b0(50|c0)
(*d4)->next = c0->next = nullptr now b0 will be replaced by nullptr i.e c0 now contains 40|null and c4 contains b0

Similarly for other nodes same steps are going on finally e0 will be nullptr

Note: one more improvement we can do here, we can even remove the (*head)->next = nullptr from reverse_ll3 and add curr->next = nullptr in main function after reverse_ll3 function call because at the end curr->next(e0) need to be nullptr.