Skip to content

Reverse a Linked List — Step by Step

Singlyn = 6≈ 72 B
prev = NULL
from head:12→7→33→5→21→48→NULL
1/22

How do you reverse a linked list?

To reverse a singly linked list in place, walk it once with three pointers — prev, curr and next — and flip each node's next pointer to point at the node before it; when curr runs off the end, prev is the new head. It takes O(n) time and O(1) extra space and is one of the most frequently asked linked-list interview questions (LeetCode 206).

How it works

  1. Start with prev = NULL (the reversed part is empty) and curr = head.
  2. Save the rest of the list: next = curr.next. Without this bookmark the next write would lose it.
  3. Flip the arrow: curr.next = prev.
  4. Advance both pointers one node: prev = curr, then curr = next.
  5. Repeat steps 2–4 until curr is NULL, then set head = prev — the old last node.

The intuition: move one node at a time

At every moment the list is split into two chains. prev is the head of the part that is already reversed; curr is the head of the part that is not. Each iteration takes the first node of the unreversed part and pushes it onto the front of the reversed part — exactly like popping from one stack and pushing onto another. When the unreversed part is empty, the reversed part is the whole list.

Three pointers are needed because flipping curr.next destroys the only link to the rest of the list. next is a bookmark taken just before that write.

Worked example: 12 → 7 → 33 → 5

Trace the loop on a four-node list:

  • Start: prev = NULL, curr = 12. Reversed: (empty). Remaining: 12 → 7 → 33 → 5.
  • Iteration 1: next = 7; 12.next = NULL; prev = 12, curr = 7. Reversed: 12. Remaining: 7 → 33 → 5.
  • Iteration 2: next = 33; 7.next = 12; prev = 7, curr = 33. Reversed: 7 → 12. Remaining: 33 → 5.
  • Iteration 3: next = 5; 33.next = 7; prev = 33, curr = 5. Reversed: 33 → 7 → 12. Remaining: 5.
  • Iteration 4: next = NULL; 5.next = 33; prev = 5, curr = NULL. Reversed: 5 → 33 → 7 → 12.
  • Finish: head = prev = 5.

Four nodes, four iterations, one pointer write per node. The visualizer above has the same loop ready to play on its six-node list, 12 → 7 → 33 → 5 → 21 → 48, and labels each pointer as it moves.

The recursive version

Recursion reverses the rest of the list first and then hooks the current node onto its end:

  • if head is None or head.next is None: return head
  • new_head = reverse(head.next) — everything after head is now reversed, and head.next is its last node.
  • head.next.next = head — that last node points back at head.
  • head.next = None — head becomes the new end.
  • return new_head

It is elegant and still O(n) time, but it uses O(n) stack space — one frame per node — so a long list can overflow the call stack (Python's default recursion limit is about 1,000 frames). The iterative version is the safer answer in production and in interviews; mention the recursive one to show you know both.

Reversing doubly and circular lists

In a doubly linked list each node has both pointers, so reversing means swapping them: as each node is visited, curr.next = prev and curr.prev = next. Afterwards head and tail swap roles. If you only need to read the list backwards, you can skip the work entirely and walk it from the tail.

In a circular list there is no NULL to start prev at. Start prev on the last node, so that when the head's arrow flips it points at the old tail and closes the reversed ring, and loop until curr comes back around to the head. Switch the list type in the visualizer to watch both variants.

Common mistakes

  • Overwriting the link before saving it. Writing curr.next = prev before next = curr.next loses the rest of the list after the first iteration.
  • Returning the old head. After the loop the old head is the last node; the new head is prev.
  • Forgetting the tail pointer, if the list keeps one: the old head becomes the new tail.
  • Not cutting the old link in the recursive version. Without head.next = None the first two nodes end up pointing at each other — a two-node cycle.
  • Skipping the edge cases: an empty list and a one-node list must come back unchanged.

Interview variations

Once the three-pointer loop is second nature, several harder problems reduce to it:

  • Reverse between positions m and n (LeetCode 92): walk to node m − 1, reverse the next n − m + 1 nodes, and reconnect both ends.
  • Reverse in groups of k (LeetCode 25): repeat that sub-list reversal for each block of k nodes.
  • Palindrome linked list (LeetCode 234): find the middle with slow and fast pointers, reverse the second half and compare the halves — O(n) time, O(1) space.
  • Add two numbers stored most-significant digit first: reverse both lists, add digit by digit with a carry, and reverse the result.

Time and space complexity

CaseTimeSpaceWhy
Iterative (three pointers)O(n)O(1)Each node is visited once and gets exactly one pointer write.
RecursiveO(n)O(n)One stack frame per node until the base case.
Doubly linked (swap next/prev)O(n)O(1)Two writes per node instead of one.
Using an explicit stackO(n)O(n)Push every node, then pop to relink — simple but wastes memory.

Reverse a Linked List in Python

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None  # next node


class LinkedList:
    def __init__(self):
        self.head = None  # first node

    def reverse(self):
        prev = None
        curr = self.head
        while curr is not None:
            nxt = curr.next   # save rest
            curr.next = prev  # flip!
            prev = curr
            curr = nxt
        self.head = prev

The visualizer above shows the same code in Python, C++, Java and JavaScript.

Frequently asked questions

What is the time and space complexity of reversing a linked list?

The iterative three-pointer method is O(n) time and O(1) extra space: every node is visited once and only three pointers are kept. The recursive method is also O(n) time but uses O(n) space for the call stack.

Why do we need three pointers to reverse a linked list?

curr is the node being flipped, prev is where its arrow should now point, and next saves the rest of the list before curr.next is overwritten. Drop any one of them and you either lose the remaining nodes or have nothing to point at.

How do you reverse a linked list recursively?

Reverse everything after the head, then make the old second node point back at the head (head.next.next = head) and set head.next = None. Return the head of the reversed rest, which is the old last node.

How do you reverse a doubly linked list?

Walk the list and swap each node's next and prev pointers, then swap head and tail. Like the singly linked version it takes O(n) time and O(1) extra space.

Can you reverse a linked list without extra space?

Yes. The iterative method reverses the list in place with three pointer variables — O(1) extra memory. No new nodes are created and no values are copied.

Keep learning

Last updated