LOGBOOK

HELP

1 / 29
Other keys: show • Space: good • 1-4: rate • 0: skip • 5: flag

Question

What is an array-list, and why is add usually $O(1)$ but occasionally $O(n)$?

Answer

An array-list wraps a plain array and resizes it automatically; an add into a free slot is $O(1)$, but an add into a full array first copies every element into a bigger one, which is $O(n)$.

An array-list of capacity 4 filling up, then doubling to 8 by copying

* The fourth add fits; the fifth finds the array full and pays for copying all four first. *

A plain array has a fixed length that is decided when it is created. An array-list hides that limitation: it keeps an internal array that is usually a bit larger than needed, plus a counter of how many slots are actually used.

  • Room left: add writes the element into the next free slot and bumps the counter. One write, independent of $n$ — $O(1)$.
  • Array full: there is nowhere to write. The list allocates a new, larger array (typically double the size), copies all $n$ existing elements across, and only then writes the new one. The copy touches every element — $O(n)$.
  • Shrinking: when many elements are removed, the array-list can also shrink its internal array again, so a list that was once huge does not hold on to the memory forever.

So the cost of a single add depends on when you call it, which is why the worst case of one operation and the typical cost differ so sharply.

Go deeper:

  • doc Dynamic array — capacity vs. size, the growth factor, and the performance table against linked lists.
  • doc java.util.ArrayList — the Java implementation; its class comment states the amortised constant-time add.
Several values are inserted at the end of a dynamic array using geometric expansion. Grey cells indicate space reserved for expansion. Most insertions are fast (constant time), while some are slow due to the need for reallocation (Θ(n) time, labelled with turtles). The logical size and capacity of the final array are shown.
Several values are inserted at the end of a dynamic array using geometric expansion. Grey cells indicate space reserved for expansion. Most insertions are fast (constant time), while some are slow due to the need for reallocation (Θ(n) time, labelled with turtles). The logical size and capacity of the final array are shown.
Dcoetzee · CC0 · Wikimedia Commons
or press any other key

Question

Why does an array-list grow by doubling its capacity rather than by adding one slot at a time?

Answer

Doubling makes the expensive copies so rare that their total cost is proportional to the number of adds — on average each add costs $O(1)$ (amortised). Growing by a constant amount makes every few adds pay a full copy, giving $O(n^2)$ for $n$ adds.

Cost of each add into a doubling array: rare tall spikes, running average below 3

* The spikes get taller but twice as far apart, so the average never climbs. *

Count the copying work for $n$ adds, starting from capacity 1.

Doubling. Copies happen when the array holds 1, 2, 4, 8, … elements. The total copied is

$$1 + 2 + 4 + \dots + \frac{n}{2} < n$$

so $n$ adds cost fewer than $n$ writes plus fewer than $n$ copies: $O(n)$ in total, $O(1)$ per add on average. Each expensive copy is "paid for" by the many cheap adds since the last one.

Growing by 1 (or by any constant $k$). Every add (or every $k$-th add) copies the whole array, so the copies cost $1 + 2 + 3 + \dots + n$ — Gauss's sum, $O(n^2)$ in total, $O(n)$ per add.

This averaging over a sequence of operations is called amortised analysis. It is not an average over random inputs: it is a guarantee that any sequence of $n$ adds costs $O(n)$, even though one individual add can cost $O(n)$.

Tip: that is why a runtime table may list addLast on an array-list as $O(n)$ (the worst single call) while the Java documentation promises "amortised constant time". Both are true; they answer different questions.

Go deeper:

Amortized analysis of the push operation for a dynamic array
Amortized analysis of the push operation for a dynamic array
Mxxxr · CC0 · Wikimedia Commons
or press any other key