Skip to content
Forge Learn/Linked Lists
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Singly Linked Lists

6 min read

You'll learn to

  • -Explain how a singly linked list chains Node objects together via next references
  • -Compare linked list insertion to array/list insertion in Big-O terms
  • -Recognize the core tradeoff: O(1) head insertion versus no random access

Every structure built so far this tier, the stack, the circular-buffer queue, the hashmap's buckets, leaned on a Python list, a contiguous array under the hood. A linked list throws that away entirely and builds a chain of separate objects instead, trading random access for genuinely cheap insertion and removal at the ends.

The Node: value + next

The building block of a linked list. One value, one pointer to the next node.

A linked list is nothing more than a chain of these Node objects. Each one points to the next, and the list itself only needs to remember where the chain starts (head) and, usually, where it ends (tail).

A minimal LinkedList with head/tail-tracked prepend and append

Why Head Insertion is O(1) Here but O(n) for a Python List

Inserting at the front of a Python list with list.insert(0, x) forces every existing element to shift one slot to the right. O(n), the exact same shifting cost as the naive queue's pop(0) from the previous module. A linked list's prepend touches only one new node and the existing head reference, two pointer assignments, full stop, regardless of how long the chain already is. That is O(1), always, no matter the list's current size.

The Tradeoff: No Random Access

The cost of that flexibility is that a linked list cannot jump directly to "the 500th element" the way arr[500] does on a Python list. Reaching any node other than the head (or the tail, if tracked) means walking the chain one next reference at a time from the head, an O(n) operation, even though the equivalent lookup on a Python list is O(1).

Operation comparison
O(1)
Insert at front (LinkedList)
O(n)
Insert at front (Python list)
O(n)
Access by index (LinkedList)
O(1)
Access by index (Python list)

This is exactly why ordinary code defaults to a Python list, reserving a hand-built linked list for specific situations: implementing another structure's internals (a queue, a stack, an LRU cache's eviction order in the tier's capstone), or anywhere O(1) insertion and removal at both ends is required without ever needing random access.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.