Ref: 2 memory walkthrough was added
This commit is contained in:
@@ -23,3 +23,8 @@ Original list:
|
|||||||
Reversed list:
|
Reversed list:
|
||||||
5 -> 4 -> 3 -> 2 -> 1 -> null
|
5 -> 4 -> 3 -> 2 -> 1 -> null
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Memory walkthrough
|
||||||
|
|
||||||
|
see memory_walkthrough.md
|
||||||
@@ -0,0 +1,827 @@
|
|||||||
|
# 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.
|
||||||
Reference in New Issue
Block a user