Data structures and algorithms path · Sequences · Topic 3 of 13

Linked lists, and when they lose to arrays

Not started

A linked list stores each element in its own small object, a node, that also holds a reference to the next node. The list itself is just a pointer to the first one. Because nodes don't have to sit next to each other, you can insert or remove an element by rewiring a couple of pointers without moving anything else. The same property is what makes them slow at almost everything else on modern hardware.

Why it matters: Textbooks praise their O(1) inserts; real hardware usually punishes them. Knowing both sides tells you the few places they are the right tool.

  1. 1Nodes and pointers

    Each element lives in its own node with a reference to the next (and, in a doubly linked list, the previous) node.

  2. 2Cheap splicing

    Given a node, inserting or removing next to it is O(1). Nothing else moves.

  3. 3Expensive finding

    There is no index. Reaching the k-th element, or searching, means walking from the head, O(n).

  4. 4Caches hate them

    Nodes are scattered in memory, so a traversal is a chain of cache misses. A plain array scan is often dozens of times faster.

1

How it works

The explanation, with examples you can run.

What they are good at

If you already hold a reference to a node, splicing next to it is O(1): point the new node at the old successor and point the old node at the new one. Removing is the same in reverse. A doubly linked list adds a prev pointer to every node so you can also remove a node without knowing its predecessor, and walk backwards.

That makes linked lists the right tool in a few real places:

  • LRU caches: a hash map from key to node, plus a doubly linked list ordered by recency. A hit unlinks the node and moves it to the front in O(1); eviction takes the node at the back.
  • Queues with unbounded growth that must never copy, and lists embedded inside other objects (the "intrusive" lists common in operating system kernels).
  • Immutable, shared lists in functional languages, where many lists share the same tail.

Here is the LRU pattern, with sentinel head and tail nodes so there are no special cases at the ends:

⌘/Ctrl + Enter
OutputNot run yet

Press Run to see what your code prints, in order.

Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.

A JavaScript Map remembers insertion order, so a simpler LRU can delete and re-insert keys instead. The linked list version is the one you will meet in other languages and in interviews.

Where they lose

There is no index, so list[k] means walking k nodes. Searching is a walk too. And every step of a walk is a pointer dereference to a node that may be anywhere in memory, which usually means a cache miss. Compare summing a million numbers stored both ways, with the nodes linked in a random order as they would be after a long-running program has inserted them over time:

⌘/Ctrl + Enter
OutputNot run yet

Press Run to see what your code prints, in order.

Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.

Both loops are O(n) and give the same sum. In Node 22 on a laptop the array took about 8 ms and the list between 750 and 1,000 ms. Each node also carries pointer and object-header overhead that an array of numbers doesn't have. This is why Java's ArrayList and ArrayDeque are usually recommended over LinkedList, and why Python's deque is built from blocks of 64 elements linked together rather than one node per item.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.You need to insert into the middle of a sequence of a million items, and you only know the position by index. Which is faster in practice?
  2. 2.An LRU cache needs O(1) lookup by key and O(1) "move this entry to the front". What is the classic structure?
  3. 3.What does a doubly linked list add over a singly linked one?

0 of 3 right so far. Get all three to finish this topic.