Skip to content
Part IA Michaelmas Term

Complexity Classes and Recurrences

Common complexity classes

Complexity classes

ClassNameGrowth rate
O(1)ConstantDoes not grow with input
O(log n)LogarithmicGrows very slowly
O(n)LinearProportional to input
O(n log n)Quasi-linearSlightly worse than linear
O(n²)QuadraticDoubling input quadruples cost
O(n³)CubicDoubling input multiplies cost by 8
O(2ⁿ)ExponentialEach additional input element doubles cost

Logarithms grow very slowly — O(log n) is excellent. Because O notation ignores constant factors, the base of the logarithm is irrelevant.

Growth rate table

How large an input can be processed in a given time:

Complexity1 second1 minute1 hourGain
n100060,0003,600,000×60
n log n1404,895204,095×41
312441,897×8
1039153×4
2ⁿ91521+6

The “gain” column shows what happens when going from 1 second to 1 minute. For exponential algorithms, the gain is a mere +6 — doubling hardware barely helps.

Exponential vs polynomial

  • Polynomial complexity (O(nᶜ)): doubling the input increases cost by a constant factor. Practical for reasonable c, though c > 3 may still be problematic.
  • Exponential complexity (O(2ⁿ)): can never handle large inputs, even with huge resources. Already with n = 20 the cost exceeds one million.

Faster hardware does not make good algorithms unnecessary. On the contrary, faster hardware magnifies the superiority of better algorithms: with sillySum (O(2ⁿ)), doubling processing power lets us go from n to n+1; with npower (O(n)), from n to 2n; with power (O(log n)), from n to n².

Simple recurrence relations

Simple recurrence relations and algorithm costs

RecurrenceClosed formComplexity
T(n+1) = T(n) + 1T(n) = nO(n)
T(n+1) = T(n) + nT(n) = n(n-1)/2O(n²)
T(n) = T(n/2) + 1T(2ⁿ) = n+1O(log n)
T(n) = 2T(n/2) + n-O(n log n)

These recurrences are read directly from OCaml definitions. The constant work in the recursive step gets unit cost; the base case also gets unit cost. Since we only need an upper bound, these units represent the larger of the actual costs.