Skip to Content
Course content

240: Whiteboard Practice: Reversing a Linked List In Place

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Alright, let's get into one of those classic whiteboard questions that makes everyone nervous: reversing a singly linked list in place. When an interviewer asks this, they aren't just checking if you know the algorithm; they're watching to see how you handle pointers without causing a segmentation fault. Let's walk through how I'd actually tackle this if I were sketching it out on a board.

The "Wait, I just broke my list" moment

Usually, my first instinct is to keep it simple. If I have a list like 1 -> 2 -> 3 -> NULL, I just want the arrows to point backward. I'll start with a current pointer at the head and a prev pointer set to NULL. My logic seems sound: just make current->next point to prev.

while (current != NULL) {
    current->next = prev; // Flip the pointer
    prev = current;       // Move prev forward
    current = current->next; // Move current forward... wait.
}

I stop right there. If I'm actually tracing this in my head, I realize I've just committed a cardinal sin of linked list manipulation. The moment I executed current->next = prev, I destroyed the only link I had to the rest of the list. If current was at node 1, current->next now points to NULL. When I try to move current forward using current = current->next, I'm not moving to node 2—I'm moving back to NULL. I've effectively orphaned the rest of my data.

Saving the future

To fix this, I need a way to remember where the rest of the list is before I sever the connection. I need a third pointer. I'll call it next_node. It's essentially a bookmark.

Let's try the sequence again. I'll grab the reference to the next node first, then I can safely flip the pointer without losing my place.

while (current != NULL) {
    struct Node* next_node = current->next; // Bookmark the next node
    current->next = prev;                  // Flip the arrow
    
    // Now I can move my trackers forward
    prev = current; 
    current = next_node; 
}

This feels much better. If I trace it with 1 -> 2 -> 3:

  • Iteration 1: next_node is 2. Node 1 now points to NULL. prev becomes 1, current becomes 2.
  • Iteration 2: next_node is 3. Node 2 now points to 1. prev becomes 2, current becomes 3.
  • Iteration 3: next_node is NULL. Node 3 now points to 2. prev becomes 3, current becomes NULL.

Dealing with the new head

Now, here is where a lot of people trip up. The loop terminates when current hits NULL. But if I return the original head of the list, I'm returning node 1, which is now the tail of my reversed list. That's not what we want.

Looking at my trace, when the loop finished, prev was sitting on node 3. That's my new head. So, the final step is simply returning prev. It's a subtle detail, but it's the difference between a working function and one that returns a list of length one.

Here is the complete logic we arrived at:

struct Node* reverseList(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* current = head;
    struct Node* next_node = NULL;

    while (current != NULL) {
        next_node = current->next; // Save next
        current->next = prev;      // Reverse
        prev = current;            // Advance prev
        current = next_node;       // Advance current
    }
    
    return prev; // prev is now the new head
}

The beauty of this approach is that it's O(n) time and O(1) space. We didn't allocate any new nodes; we just shuffled some addresses around. In a real interview, I'd mention that this handles an empty list (head == NULL) and a single-node list perfectly without needing extra if statements.




📋 Practical Task

Exercise: Implement a Reverse-and-Print Linked List Utility

Write a complete C program that does the following:

  • Defines a Node struct containing an integer data and a struct Node* next pointer.
  • Implements a function struct Node* reverseList(struct Node* head) using the in-place logic discussed in the lesson.
  • Implements a helper function void printList(struct Node* head) to display the list elements.
  • In main, manually create a linked list with at least four elements (e.g., 10 → 20 → 30 → 40), print it, reverse it using your function, and print the reversed list to verify the result.

Constraint: You must not use any additional arrays or temporary lists to store the values; the reversal must happen by manipulating the pointers of the existing nodes.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.