I · The linear primitives

Dynamic array (vector)

An array that grows itself.

The story

How do you have an array but not know its size in advance? Allocate too small, double when full, copy. Amortised O(1) append. The growth factor is folklore (Java uses 1.5×, Go and Python use ~1.25×, C++ commonly 2×), and each pick costs differently in memory vs copies.

How it works

Maintain (data, len, cap). On append if len = cap, allocate 2 × cap, memcpy old data, free old block. The amortisation: total copies ≤ 2n across n appends, so per-append average is O(1).

Where it lives

C++ std::vector, Rust Vec, Go slice, Python list, Java ArrayList, JavaScript Array. Almost every "list" you've ever used.

The key insight

Growth factor is a memory-vs-time tradeoff. 2× wastes up to 50% memory but minimises copies. 1.5× wastes only 33% but copies more often. There is no right answer — only profiling.