šŸ”„ 0
⭐ 0
Lesson 7 of 10 15 min +100 XP

Linked Lists

A Linked List is a linear data structure where elements are stored in nodes. Each node contains data and a reference (pointer) to the next node in the sequence.

Linked List Data Structure

Node Structure

class Node {
  constructor(data) {
    this.data = data;  // The value
    this.next = null;  // Pointer to next node
  }
}

Arrays vs Linked Lists

AspectArrayLinked List
MemoryContiguousScattered
AccessO(1) random accessO(n) sequential
Insert at startO(n) shift elementsO(1)
Insert at endO(1) amortizedO(n) or O(1)
Memory overheadNoneExtra pointer per node
Cache performanceExcellentPoor
O(1) if we maintain a tail pointer

Implementation

Singly Linked List

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

  // Insert at head - O(1)
  insertAtHead(data) {
    const newNode = new Node(data);
    newNode.next = this.head;
    this.head = newNode;
    this.size++;
  }

  // Insert at tail - O(n)
  insertAtTail(data) {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
    } else {
      let current = this.head;
      while (current.next) {
        current = current.next;
      }
      current.next = newNode;
    }
    this.size++;
  }

  // Delete at head - O(1)
  deleteAtHead() {
    if (!this.head) return null;
    const data = this.head.data;
    this.head = this.head.next;
    this.size--;
    return data;
  }

  // Search - O(n)
  search(data) {
    let current = this.head;
    let index = 0;
    while (current) {
      if (current.data === data) return index;
      current = current.next;
      index++;
    }
    return -1;
  }

  // Print list
  print() {
    let current = this.head;
    const elements = [];
    while (current) {
      elements.push(current.data);
      current = current.next;
    }
    console.log(elements.join(' → ') + ' → NULL');
  }
}

// Usage
const list = new LinkedList();
list.insertAtHead(42);
list.insertAtHead(25);
list.insertAtHead(10);
list.print(); // 10 → 25 → 42 → NULL

Types of Linked Lists

1. Singly Linked List

Each node points to the next node only.

[10|→] → [25|→] → [42|→] → NULL

2. Doubly Linked List

Each node points to both previous and next nodes.

NULL ← [←|10|→] ⟷ [←|25|→] ⟷ [←|42|→] → NULL
class DoublyNode {
  constructor(data) {
    this.data = data;
    this.prev = null;
    this.next = null;
  }
}

3. Circular Linked List

The last node points back to the first node.

[10|→] → [25|→] → [42|→] ─┐
  ↑                        │
  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Common Operations

OperationSinglyDoubly
Insert at headO(1)O(1)
Insert at tailO(n)O(1)
Delete at headO(1)O(1)
Delete at tailO(n)O(1)
SearchO(n)O(n)
Reverse traversalO(n)O(1)

*With tail pointer

Classic Problem: Reverse a Linked List

function reverse(head) {
  let prev = null;
  let current = head;

  while (current) {
    const next = current.next; // Save next
    current.next = prev;       // Reverse pointer
    prev = current;            // Move prev forward
    current = next;            // Move current forward
  }

  return prev; // New head
}

When to Use Linked Lists

Good for:
  • Frequent insertions/deletions at the beginning
  • Unknown or variable size
  • Implementing stacks and queues
  • When you don't need random access
Not ideal for:
  • Random access patterns
  • Small data sets (array overhead is less)
  • Cache-sensitive applications

What's Next?

Next, we'll explore Trees — hierarchical data structures that extend the concept of linked nodes into branching structures, perfect for representing hierarchies and enabling fast searching.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What is the time complexity of inserting at the head of a linked list?

2

What is a disadvantage of linked lists compared to arrays?

3

In a doubly linked list, each node contains:

Queues