# Reverse Linked List — Memory Walkthrough This walkthrough explains the classic three-pointer linked list reversal using a memory-oriented view. The goal is not only to show that the algorithm works, but also to show what happens to: - stack variables - heap nodes - `next` fields inside each node The example list contains three nodes: ```text 1 -> 2 -> 3 -> null ``` For clarity, fake addresses are used: ```text Node 1: 0x1000 Node 2: 0x2000 Node 3: 0x3000 ``` These addresses are illustrative only. A real program will use different addresses. --- ## Algorithm ```cpp Node* reverseList(Node* head) { Node* previous = nullptr; Node* current = head; while(current != nullptr) { Node* next = current->next; current->next = previous; previous = current; current = next; } return previous; } ``` The three important pointers are: | Pointer | Meaning | |---|---| | `previous` | Head of the already reversed part | | `current` | Node currently being processed | | `next` | Saved pointer to the remaining original list | The most important rule is: > Save `next` before changing `current->next`. Otherwise the rest of the original list may become unreachable. --- ## Step 0 — Initial State Before the loop starts: ```cpp Node* previous = nullptr; Node* current = head; ``` ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | nullptr | | current | 0x1000 | | next | not set | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=2000 | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text head/current | v 1 -> 2 -> 3 -> null previous -> null ``` At this point, nothing has been reversed yet. --- ## Step 1 — Save `next` Inside the first loop iteration: ```cpp Node* next = current->next; ``` `current` points to Node 1. `current->next` points to Node 2. So: ```text next = 0x2000 ``` ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | nullptr | | current | 0x1000 | | next | 0x2000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=2000 | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` Nothing in the heap changed yet. The `next` stack variable only saves access to the rest of the list. Without this temporary pointer, Node 2 and Node 3 could be lost after the next operation. --- ## Step 2 — Reverse `current->next` Now the algorithm changes the link: ```cpp current->next = previous; ``` `current` is Node 1. `previous` is `nullptr`. So Node 1 no longer points to Node 2. It now points to `nullptr`. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | nullptr | | current | 0x1000 | | next | 0x2000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text current | v 1 -> null next | v 2 -> 3 -> null ``` This is the key mutation. The original list is now split into two logical parts: ```text Reversed part: 1 -> null Remaining original part: 2 -> 3 -> null ``` --- ## Step 3 — Move `previous` The algorithm advances the reversed part: ```cpp previous = current; ``` `previous` now points to Node 1. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x1000 | | current | 0x1000 | | next | 0x2000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text previous/current | v 1 -> null next | v 2 -> 3 -> null ``` The reversed part now officially starts at `previous`. --- ## Step 4 — Move `current` The algorithm continues with the saved next node: ```cpp current = next; ``` `current` now points to Node 2. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x1000 | | current | 0x2000 | | next | 0x2000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text previous | v 1 -> null current | v 2 -> 3 -> null ``` The first iteration is complete. --- ## Step 5 — Second Iteration: Save `next` The loop repeats. ```cpp Node* next = current->next; ``` `current` points to Node 2. Node 2 points to Node 3. So: ```text next = 0x3000 ``` ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x1000 | | current | 0x2000 | | next | 0x3000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=3000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` Again, the heap has not changed yet. --- ## Step 6 — Second Iteration: Reverse Link ```cpp current->next = previous; ``` `current` is Node 2. `previous` is Node 1. So Node 2 now points back to Node 1. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x1000 | | current | 0x2000 | | next | 0x3000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text current | v 2 -> 1 -> null next | v 3 -> null ``` The reversed part will become: ```text 2 -> 1 -> null ``` after `previous` moves to Node 2. --- ## Step 7 — Second Iteration: Move Pointers ```cpp previous = current; current = next; ``` ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x2000 | | current | 0x3000 | | next | 0x3000 | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` ### Logical view ```text previous | v 2 -> 1 -> null current | v 3 -> null ``` Now two nodes are reversed. --- ## Step 8 — Third Iteration: Save `next` ```cpp Node* next = current->next; ``` `current` is Node 3. Node 3 points to `nullptr`. So: ```text next = nullptr ``` ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x2000 | | current | 0x3000 | | next | nullptr | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=null | +-----------+-----------+ ``` --- ## Step 9 — Third Iteration: Reverse Link ```cpp current->next = previous; ``` `current` is Node 3. `previous` is Node 2. So Node 3 now points to Node 2. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x2000 | | current | 0x3000 | | next | nullptr | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=2000 | +-----------+-----------+ ``` ### Logical view ```text current | v 3 -> 2 -> 1 -> null ``` The whole list is now reversed, but the loop still needs to update the stack pointers. --- ## Step 10 — Third Iteration: Move Pointers ```cpp previous = current; current = next; ``` Since `next` is `nullptr`, `current` becomes `nullptr`. ### Stack ```text +----------+----------+ | Variable | Value | +----------+----------+ | head | 0x1000 | | previous | 0x3000 | | current | nullptr | | next | nullptr | +----------+----------+ ``` ### Heap ```text 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x3000 +-----------+-----------+ | value = 3 | next=2000 | +-----------+-----------+ ``` ### Logical view ```text previous | v 3 -> 2 -> 1 -> null current -> null ``` The loop condition fails: ```cpp while(current != nullptr) ``` because `current` is now `nullptr`. --- ## Step 11 — Return New Head At the end: ```cpp return previous; ``` `previous` points to Node 3. Node 3 is the new head of the reversed list. ### Final stack view ```text +----------+----------+ | Variable | Value | +----------+----------+ | old head | 0x1000 | | new head | 0x3000 | +----------+----------+ ``` ### Final heap view ```text 0x3000 +-----------+-----------+ | value = 3 | next=2000 | +-----------+-----------+ 0x2000 +-----------+-----------+ | value = 2 | next=1000 | +-----------+-----------+ 0x1000 +-----------+-----------+ | value = 1 | next=null | +-----------+-----------+ ``` ### Final logical view ```text new head | v 3 -> 2 -> 1 -> null ``` --- ## Why the Temporary `next` Pointer Matters This line is not optional: ```cpp Node* next = current->next; ``` Without it, this operation: ```cpp current->next = previous; ``` would overwrite the only pointer to the remaining original list. For example, at the beginning: ```text 1 -> 2 -> 3 -> null ``` If Node 1 is changed to: ```text 1 -> null ``` before saving Node 2, then Node 2 and Node 3 are no longer reachable from any local variable. That is why the algorithm always follows this order: ```cpp Node* next = current->next; // preserve the remaining list current->next = previous; // reverse the link previous = current; // grow the reversed part current = next; // continue with the remaining part ``` The order is the algorithm. --- ## Summary During the algorithm: - `previous` points to the already reversed part. - `current` points to the node being processed. - `next` preserves access to the not-yet-processed part. - Only one `next` field is modified per iteration. - No nodes are copied. - No new list is allocated. - The original nodes are relinked in-place. The algorithm is small, but it is easy to get wrong because it mutates the structure while traversing it. That is why a memory-level walkthrough is often more useful than just showing the final code.