Kazi Rahamatullah
Kazi Rahamatullah
AboutProjectsBlogContact
UsesBooks
ResumeView CV
Kazi Rahamatullah

© Copyright 2026 Kazi Rahamatullah

AboutProjectsBlogBooksUses
Twitter/XGitHubProduct HuntCodeSandbox
Back to Blog
DSALinked ListsData StructuresAlgorithms

DSA Linked Lists — Fundamentals Visualized

Learn linked list fundamentals — nodes, head pointer, next links, traversal, vs arrays, with interactive step visualizer and complexity analysis.

Jul 4, 20264 min read

Introduction

Linked lists store elements as nodes chained by pointers — unlike arrays, memory is not contiguous. Each node holds a value and a reference to the next node; head is the entry point.

This guide covers:

  1. Node structure — value + next pointer
  2. Interactive visualizer — head, tail, traversal
  3. vs arrays — trade-offs at a glance
  4. When to choose — dynamic size, frequent head inserts

Quick index

#Section
1How linked lists work
2Interactive visualizer
3Full implementation
4vs Arrays
5When to use
6Real-life examples

1. How linked lists work

plaintext
head → [10 | next] → [20 | next] → [30 | null]
ConceptMeaning
Node{ value, next } object
headReference to first node
tailLast node (next = null)
TraversalFollow next until null
js
class Node {
  constructor(value) {
    this.value = value
    this.next = null
  }
}
 
const head = new Node(10)
head.next = new Node(20)
head.next.next = new Node(30)

Back to index


2. Interactive visualizer

Linked List — Fundamentals

Head pointer, nodes, next links, and traversal — the building blocks of every linked list variant.

Structure

head
ref→
10
next
n1
→
20
next
n2
→
30
next
n3
→
null
↑ tail

Each node stores a value and a pointer (next) to the following node.

Singly linked node

class Node {
constructor(value) { this.value = value; this.next = null }
}
let head = new Node(10)entry point

head is a reference to the first node — not the whole list.

Access i

O(n)

Insert head

O(1)

Space

O(n)

Tip

Yellow = head node. Step through traversal to see why reaching index i costs O(i) pointer hops.

Back to index


3. Full implementation

js
class Node {
  constructor(value) {
    this.value = value
    this.next = null
  }
}
 
class LinkedList {
  constructor() {
    this.head = null
    this.tail = null
  }
 
  prepend(val) {
    const node = new Node(val)
    if (!this.head) this.tail = node
    node.next = this.head
    this.head = node
  }
 
  append(val) {
    const node = new Node(val)
    if (!this.head) {
      this.head = this.tail = node
      return
    }
    this.tail.next = node
    this.tail = node
  }
 
  toArray() {
    const out = []
    let cur = this.head
    while (cur) {
      out.push(cur.value)
      cur = cur.next
    }
    return out
  }
}

Function calls with output

js
// ── Demo calls — output shown on the right ──
const list = new LinkedList()
 
list.prepend(10) // → [10]
list.prepend(5) // → [5, 10]
list.append(20) // → [5, 10, 20]
list.toArray() // → [5, 10, 20]

Back to index


4. vs Arrays

OperationArrayLinked List
Access index iO(1)O(n)
Insert at headO(n) shiftO(1)
Insert at tailO(1)*O(n) or O(1) with tail
MemoryContiguous, cache-friendlyScattered nodes + pointer overhead
SizeFixed or resize copyGrows one node at a time

Back to index


5. When to use

Use linked lists whenPrefer arrays when
Frequent head inserts/deletesRandom access by index
Unknown or highly variable sizeCache locality matters
Implementing stack/queue adjacencyBinary search needed

Interview Answer

"Why can't you binary search a linked list?"

Binary search needs O(1) access to the middle element. Linked lists require O(n) traversal to reach any index — no random access.

Back to index


6. Real-life examples

Real-world structureLinked list role
Music playlistEach song node points to next — add/remove tracks without shifting
Browser history (back stack)Each page visit is a node — push/pop at head
Undo/redo in editorsAction nodes chained — traverse for undo stack
Hash map collision chainsBuckets use singly linked lists when keys collide
Task queue in job schedulersFIFO queue built on linked nodes — O(1) enqueue

Music playlist

Each song is a node — insert or remove tracks by rewiring pointers, no array shift.

head
ref→
Song A
next
n0
→
null
↑ tail

head points to first node — O(1) start playback.

Real-world implementation

class SongNode {
  constructor(title) { this.title = title; this.next = null }
}

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

  addNext(title) {
    const node = new SongNode(title)
    if (!this.head) { this.head = this.current = node; return }
    node.next = this.current.next
    this.current.next = node
  }

  playNext() {
    if (this.current?.next) this.current = this.current.next
    return this.current?.title ?? null
  }

  toArray() {
    const out = []; let cur = this.head
    while (cur) { out.push(cur.title); cur = cur.next }
    return out
  }
}

Full working code for the scenario above.

Function calls with output

// ── Function calls with output ──
const playlist = new Playlist()
playlist.head = new SongNode("Song A")→ ["Song A"]

Side output shows return value after each call — step through to trace execution.

Back to index


Summary

Linked lists trade random access for flexible size and O(1) head insertion. Master nodes and pointers here before types and operations.

Next reads: Linked Lists in Memory · Linked List Types

Share this article

XLinkedInFacebook
Kazi Rahamatullah

Written by

Kazi Rahamatullah

FullStack Developer

X / TwitterGitHubLinkedIn

Subscribe to my newsletter

Stay up to date and get notified when I share new contents.

No spam ever, unsubscribe anytime