Nothing is rewired on the way down.
Five frames pile up without changing a single pointer. Then, on the way back up, each frame flips exactly one link.
Five nodes, each pointing at the next. Press Next to make the first call.
prev at the deepest call and rides back up through all five returns untouched. That is why return prev is the same value in every frame.head->next->next = head flips one segment; head->next = nullptr makes this node the tail. Four frames, four flips.At the moment prev = reverseList(head->next) returns in the frame for node 3, nodes 4 and 5 are already reversed and node 4 is now the tail of that reversed part. Nobody touched node 3's next, so it still points straight at node 4.
You never verify the assumption. You grant it, then do one honest step of work with what it handed you.
head == nullptr — the empty list, and the guard that stops head->next from dereferencing null.head->next == nullptr — a single node, already reversed. This is the half that produces prev. Remove it and the recursion walks into nullptr, then crashes on head->next->next.Put a breakpoint on head->next->next = head;, run with F5, and press Continue four times. head->val arrives as 4, then 3, 2, 1 — innermost first, exactly as above.
Cost: O(n) time, one pass. O(n) space, because all n frames are open at the deepest point. The iterative three-pointer version is the O(1)-space answer.