structures/primer
Interactive primer

Data Structures

The shapes data takes so a program can store it, find it again, and change it without falling apart. Touch every example below.

↑ the same six values, just bytes in memory — until you give them a shape
00

What a data structure actually is

A data structure is an agreement about how values are arranged in memory and what operations are cheap as a result. The values don't change — six numbers are six numbers — but the arrangement decides whether "find the 5th item" or "add to the front" costs one step or a thousand.

Every choice is a trade. Lay items out in one contiguous block and you get instant lookup by position but slow inserts. Link them with pointers and inserts get cheap but lookup-by-position gets slow. The rest of this page lets you feel those trade-offs by running the operations yourself.

How we measure cost: Big-O counts steps as the data grows O(1) constant — same cost at any size O(log n) halves the work each step O(n) cost grows with the data
01

Array

Values packed side by side in one continuous block. Each slot has an index, so the computer reaches any element by simple arithmetic — instantly. The catch: inserting at the front means physically shifting everything else over.

ready
access O(1) append O(1)* insert front O(n) search value O(n)
02

Linked list

Each value lives in its own node that also holds a pointer to the next one. Nothing is contiguous, so adding to the front is just re-aiming one pointer — cheap. But to reach the 5th node you must walk from the head, one hop at a time.

ready
add head O(1) access by position O(n) search O(n)
03

Stack — last in, first out

A stack only lets you touch the top. You push a value on and pop the most recent one off — like a pile of plates. This is exactly how a program tracks nested function calls and "undo" history.

empty
push O(1) pop O(1) peek O(1)
04

Queue — first in, first out

A queue is fair: items leave in the order they arrived. You enqueue at the rear and dequeue from the front — a checkout line. Used anywhere work waits its turn: print jobs, task schedulers, message buffers.

empty
enqueue O(1) dequeue O(1)
05

Hash table

Instead of searching, a hash table computes where a value should live. A hash function turns your key into a bucket number, so lookups are near-instant. Type a key — watch it get hashed and dropped into a bucket. Two keys landing in the same bucket is a collision; we just chain them.

enter a key →
insert O(1) avg lookup O(1) avg worst case O(n) all collide
06

Binary search tree

Every node has up to two children, and the rule never breaks: smaller values go left, larger go right. That ordering lets search discard half the remaining tree at each step — the same idea as finding a word in a dictionary without reading every page.

ready
search O(log n) balanced insert O(log n) balanced worst case O(n) degenerate
07

Choosing the right one

There's no "best" structure — only the right fit for the operations you do most. Average-case costs below; the right structure turns a slow column green.

StructureAccess by positionSearch by valueInsertDeleteBest for
ArrayO(1)O(n)O(n)O(n)fixed lists, fast indexing
Linked listO(n)O(n)O(1)O(1)frequent front edits
StackO(n)O(1)O(1)undo, call tracking
QueueO(n)O(1)O(1)scheduling, buffering
Hash tableO(1)O(1)O(1)lookups by key
Binary search treeO(log n)O(log n)O(log n)sorted, range queries
remember

Layout is a trade

Contiguous memory buys fast indexing; pointers buy fast edits. You rarely get both at once.

remember

Order the work, not the data

Pick the structure by which operation you run thousands of times, not by what looks neat.

remember

Big-O is about growth

It ignores small inputs. O(1) vs O(n) only matters once n gets large.