Intuition
A treasure hunt where each clue tells you where the next one is hidden. You can’t jump to clue 7; you have to follow clues 1 to 6. But adding a new clue at the start is easy: write it so it points at the old first clue.
That’s a linked list. Unlike an array, the items don’t sit side by side in memory, so inserting never shifts anything. The price is that finding item i means following i pointers.
How it works
Each node holds a value and next, a pointer to the following node (or null at the end). The list itself only stores head, the first node.
- Prepend: make a node pointing at the current head, then make it the head. Two pointer changes, O(1).
- Append: walk from the head until
nextis null, then point that node at the new one. O(n), unless you keep a tail pointer. - Remove: walk with two pointers,
prevandcur, untilcurholds the value. Then pointprev.nextpastcur. Ifcuris the head, move the head instead.
Arrays or linked lists?
| Operation | Array | Linked list |
|---|---|---|
| Read item i | O(1) | O(n) |
| Insert or remove at the front | O(n) | O(1) |
| Insert or remove after a node you already have | O(n) | O(1) |
| Memory per item | Just the value | Value plus a pointer |
| Cache friendliness | Excellent | Poor: nodes are scattered |
In practice, arrays win most of the time because modern CPUs read neighbouring memory very fast. Linked lists shine when you insert and remove in the middle a lot and already hold a pointer to the spot, as in LRU caches and many kernel data structures.
Common mistakes
- Losing the rest of the list. Changing
cur.nextbefore saving it drops every node aftercur. - Forgetting the empty and one-node cases. Removing the head, or appending to an empty list, needs its own branch.
- Walking off the end. Check
curfor null before readingcur.value. - Using a linked list for random access. If you index by position, use an array.
In other languages
| Language | Built-in linked list |
|---|---|
| Python | None; collections.deque covers most uses |
| JavaScript | None |
| Java | LinkedList (doubly linked) |
| C | None; written by hand everywhere |
| Go | container/list (doubly linked) |
| Rust | std::collections::LinkedList (doubly linked; rarely the best choice) |
Check yourself
Check yourself
With only a head pointer, which operation is O(1) on a singly linked list?
Prepending only touches the head. Appending and removing the last node both need a walk to the end first.
Check yourself
To remove 7 from 3 → 7 → 12, which pointer changes?
3’s next changes from 7 to 12. Nothing points at 7 any more, so it is out of the list.
Sources
- Donald Knuth, The Art of Computer Programming, Vol. 1, section 2.2.3, “Linked Allocation.”
- Cormen, Leiserson, Rivest and Stein, Introduction to Algorithms, section 10.2, “Linked lists” (3rd edition).
Finished this page?
Your list