Asymptotic Notations
BasisPrerequisites
You want to say that binary search is “faster” than linear search. But faster on what hardware? With what compiler settings? For inputs of what size? To make comparisons that hold regardless of machine, language, and constant factors, you need a precise language for describing growth rates — and that language is asymptotic notation.
This checkpoint defines the three core notations — , , and — from first principles, and shows how they let you classify algorithms by the shape of their scaling behavior rather than their absolute performance.
The core idea: bounding a function
Let be the number of operations an algorithm performs on an input of size . You rarely know the exact formula for — it depends on constant factors that vary between machines and implementations. What you can determine is the shape of : whether it grows like , like , like , or like .
Asymptotic notation captures that shape by asking: what simpler function can you use to bound from above, from below, or both — at least for all sufficiently large ?
The phrase “for sufficiently large ” is essential. You are not making a claim about small inputs, where constant factors dominate. You are describing what happens as , which is what determines long-run scalability.
Big-O: upper bounds
Big-O notation expresses that a function is bounded above by a multiple of another function, eventually.
Definition. if and only if there exist constants and such that
In plain language: grows no faster than , up to a constant multiple. The constants and act as witnesses — you just need them to exist, not to be small.
Example. Show that .
You need and such that for all . For , each of and is at most , so:
Taking and satisfies the definition. Therefore .
One subtlety: is also true by the definition — is an upper bound too. But is the tightest upper bound, and that is always the one worth reporting.
Big-Ω: lower bounds
Big-Ω notation is the mirror of big-O: it expresses that a function is bounded below by a multiple of another function.
Definition. if and only if there exist constants and such that
In plain language: grows at least as fast as , up to a constant multiple.
Example. Show that .
For all : . Taking and satisfies the definition.
Big-Ω is used to express lower bounds on algorithms: “any algorithm for this problem must perform at least comparisons” means no algorithm can sort faster than in the comparison model.
Big-Θ: tight bounds
When a function is simultaneously and , it is bounded above and below by multiples of — it grows at exactly the same rate as , up to constants.
Definition. if and only if
Equivalently, there exist constants and such that
Example. , as the two earlier proofs together establish.
When you have a bound, you have a complete picture: the growth rate is pinned down, not just bounded from one side.
Using limits to determine the notation
Since you are already comfortable with limits from Limits, there is a practical shortcut. For positive functions and , compute:
The value of tells you the relationship directly:
| Relationship | Meaning | |
|---|---|---|
| grows strictly slower than | ||
| and grow at the same rate | ||
| grows strictly faster than |
The lowercase notations (little-o) and (little-omega) are the strict versions of and : means the ratio , while only requires the ratio to be bounded. Every relationship implies the corresponding relationship, but not vice versa.
Example. Is ?
so , which implies . In fact grows strictly slower than .
Example. Is ?
so — it grows strictly faster. Therefore .
Common growth rates
The table below lists the classes you will encounter most often, from slowest to fastest growth:
| Notation | Name | Example |
|---|---|---|
| Constant | Array access by index | |
| Logarithmic | Binary search | |
| Linear | Scanning a list once | |
| Linearithmic | Merge sort | |
| Quadratic | Comparing all pairs | |
| Cubic | Naive matrix multiplication | |
| Exponential | Brute-force subset search | |
| Factorial | Brute-force permutation |
These classes form a strict hierarchy under the relation:
An algorithm with running time will always outperform an algorithm on large enough inputs, regardless of the constant factors.
Common misconceptions
“Big-O gives the exact running time.” It does not. says the running time is bounded by for some constant — it says nothing about ‘s size. An algorithm that does operations is , as is one that does operations. Big-O describes shape, not magnitude.
“The algorithm with the smallest big-O is always fastest in practice.” Not for small inputs. An algorithm may be slower than an one for small if the former has a much larger constant factor. Asymptotic analysis describes large- behavior; for small inputs, you need to measure.
” means .” No. expresses an upper bound, not approximate equality. A constant function is , but that tells you almost nothing useful. Always report the tightest bound you can establish.
Summary
- Big-O (): is eventually bounded above by for some constant — ” grows no faster than .”
- Big-Ω (): is eventually bounded below by — ” grows at least as fast as .”
- Big-Θ (): both bounds hold — ” and grow at the same rate, up to constants.”
- The limit tells you the relationship directly: means , finite and positive means , means .
- The growth hierarchy from slow to fast: .
- Big-O is an upper bound on growth rate, not an approximation — it does not reveal constant factors or exact formulas.