← Back to DevBytes

Solving Reverse a Linked List in JavaScript: Step-by-Step Guide

Introduction to Linked Lists

A linked list is a fundamental data structure in computer science. Unlike arrays, which store elements in contiguous memory locations, a linked list consists of nodes where each node contains data and a reference (or pointer) to the next node in the sequence. This structure allows for efficient insertion and deletion of elements at the beginning of the list, as you do not need to shift elements like you would in an array.

Reversing a linked list is one of the most classic algorithmic problems. It is a frequent topic in technical interviews because it thoroughly tests a candidate's understanding of pointers, memory manipulation, and edge cases. Mastering this problem builds a strong foundation for tackling more complex data structure and algorithm challenges.

Understanding the Problem

When we talk about reversing a linked list, we mean changing the direction of the pointers so that the last node becomes the first, and the first node becomes the last. For example, if we have a linked list 1 -> 2 -> 3 -> 4 -> null, reversing it will result in 4 -> 3 -> 2 -> 1 -> null.

To achieve this, we need to traverse the list and, for each node, change its next pointer to point to the previous node instead of the next one. Because changing the pointer of the current node would cause us to lose the reference to the rest of the list, we must carefully keep track of the previous, current, and next nodes.

Implementing a Linked List in JavaScript

Before we can reverse a linked list, we need to define what a node and a linked list look like in JavaScript. Below is a basic implementation of a singly linked list.

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
  }

  // Helper method to add a node to the end of the list
  append(value) {
    const newNode = new Node(value);
    if (this.head === null) {
      this.head = newNode;
      return;
    }
    let current = this.head;
    while (current.next !== null) {
      current = current.next;
    }
    current.next = newNode;
  }

  // Helper method to print the list
  print() {
    let current = this.head;
    const values = [];
    while (current !== null) {
      values.push(current.value);
      current = current.next;
    }
    console.log(values.join(' -> '));
  }
}

Step-by-Step Guide: Reversing a Linked List

There are two primary ways to reverse a linked list: iteratively and recursively. Both approaches are valid, but they differ in their space complexity and implementation style.

The Iterative Approach

The iterative approach is generally preferred in production code because it uses a constant amount of extra memory (O(1) space complexity). We use three pointers—prev, current, and next—to traverse the list and reverse the links one by one.

Here is the step-by-step logic:

reverseIterative() {
  let prev = null;
  let current = this.head;
  
  while (current !== null) {
    // Store the next node
    const next = current.next;
    
    // Reverse the pointer
    current.next = prev;
    
    // Move pointers forward
    prev = current;
    current = next;
  }
  
  // Update the head of the list
  this.head = prev;
}

The Recursive Approach

The recursive approach is elegant but uses O(n) space complexity due to the call stack. The idea is to recursively reach the end of the list. Once the base case (the last node) is reached, we start returning and reversing the pointers on the way back up the call stack.

reverseRecursive() {
  // Helper function to handle the recursion
  const reverse = (node) => {
    // Base case: if node is null or it's the last node, return it
    if (node === null || node.next === null) {
      return node;
    }
    
    // Recursively reverse the rest of the list
    const newHead = reverse(node.next);
    
    // Reverse the pointer between the next node and the current node
    node.next.next = node;
    
    // Break the original pointer
    node.next = null;
    
    return newHead;
  };
  
  this.head = reverse(this.head);
}

Best Practices

Conclusion

Reversing a linked list is a foundational algorithm that every developer should understand. By breaking down the problem into manageable steps—keeping track of previous, current, and next nodes—you can easily implement an iterative solution that is both time and space efficient. While the recursive solution offers a cleaner, more mathematical expression of the problem, it is important to be aware of its memory limitations. Practicing both approaches will significantly improve your ability to think critically about pointers and data structures in JavaScript.

🛠 Tools from DevBytes

Inventory Tracker Pro — Excel inventory system, low-stock alerts · $19
AI Dev Kit for Mac — local AI dev environment templates · $9.99
KeyMapper for Mac — custom keyboard shortcut toolkit · $7.99

← Back to all articles