Core Module
12 min forge

Doubly Linked List

Explore bidirectional navigation in linked structures. Learn why two pointers are often better than one.

πŸ” Doubly Linked List: Bidirectional Power

A Doubly Linked List (DLL) is a complex version of a Singly Linked List where each node has two pointers: one pointing to the next node and one pointing to the previous node.

πŸ’‘ The Logic (ELI5)

Think of a Linked List as a Train:

  • Singly Linked: You can walk from the engine to the caboose, but the doors only open one way. You can't walk back.
  • Doubly Linked: Every car has a door to the car in front AND the car behind. You can walk back and forth as much as you want.

πŸ” The Deep Dive

Advantages over Singly Linked Lists

  1. Bidirectional Traversal: You can traverse from tail to head.
  2. Easier Deletion: If you have a reference to a node, you can delete it in $O(1)$ time because you already know its predecessor. In a Singly Linked List, you'd have to find the predecessor first ($O(n)$).
  3. Better for certain Data Structures: Essential for implementing Deques (Double Ended Queues) and LRU Caches.

The Cost

  • Memory: Every node needs extra space for the prev pointer (usually 8 bytes on 64-bit systems).
  • Complexity: Every insertion/deletion requires updating twice as many pointers. Fail to update one, and your list "breaks".

πŸ› οΈ Code Forge: DLL Implementation

javascript Standard
/** * A Doubly Linked Node */ class DLLNode { constructor(value) { this.value = value; this.next = null; this.prev = null; // New pointer! } } /** * Basic DLL Operations */ class DoublyLinkedList { constructor() { this.head = null; this.tail = null; } // Insert at the end - O(1) append(value) { const newNode = new DLLNode(value); if (!this.head) { this.head = this.tail = newNode; return; } this.tail.next = newNode; newNode.prev = this.tail; this.tail = newNode; } // Delete a specific node - O(1) if you have the node reference deleteNode(node) { if (node.prev) node.prev.next = node.next; else this.head = node.next; if (node.next) node.next.prev = node.prev; else this.tail = node.prev; // Clean up pointers (optional) node.prev = node.next = null; } }

🎯 Interview Pulse

Key Use Cases

  • Browser History: Moving forward and backward through pages.
  • LRU Cache: Moving the "Most Recently Used" item to the front and removing the "Least Recently Used" from the back.
  • Undo/Redo: Navigating states.

Common Questions

  • Reverse a Doubly Linked List.
  • Design an LRU Cache (The most common "Advanced" list question).
  • Implement a Deque using a DLL.
  • QuickSort and MergeSort on Doubly Linked Lists.