Week 5, Monday
February 2, 2026
We’ve seen:
Question: Is \(O(n \log n)\) the best we can do?
Or is there some clever algorithm that sorts in \(O(n)\)?
Theorem: Any comparison-based sorting algorithm requires \(\Omega(n \log n)\) comparisons in the worst case.
This means:
Every comparison-based sort makes decisions by comparing pairs of elements:
if arr[i] < arr[j]:
...
else:
...
We can model the algorithm as a binary tree of decisions.
Suppose we want to sort \([v_1, v_2, v_3]\).
Note:
How many different rearrangements are possible for an \(n\) element list?
Each ordering needs its own leaf (otherwise we’d give the same answer for different inputs).
The decision tree must have at least \(n!\) leaves!
Whose answer we need now…
A decision tree of height \(h\) has at most _______ leaves?
Recall: The height of the decision tree is the maximum number of comparisons in the worst case.
If the tree has height \(h\), then:
Therefore: \(2^h \geq n!\)
Taking logarithms: \(h \geq \log_2(n!)\)
Claim: \(\log(n!) = \Omega(n\log n)\)
Proof: \[ \begin{align} \log(n!) &= \log n + \log(n-1) + \cdots + \log 2 + \log 1 \\ &\geq \log n + \log(n-1) + \cdots + \log\left(\tfrac{n}{2}\right) & \text{(drop small half)} \\ &\geq \tfrac{n}{2} \cdot \log\left(\tfrac{n}{2}\right) & \text{(each term } \geq \log(n/2)\text{)} \\ &= \tfrac{n}{2}\log n - \tfrac{n}{2} \\ &= \tfrac{n}{4}\log n + \tfrac{n}{4}\log n - \tfrac{n}{2} \\ &\geq \tfrac{n}{4}\log n & \text{(when } \log n \geq 2 \text{, i.e., } n \geq 4\text{)} \\ &= \Omega(n \log n) \quad \blacksquare \end{align} \]
Observation: Any comparison-based sorting algorithm requires \(\Omega(n \log n)\) comparisons in the worst case.
Justification:
| Algorithm | Worst Case | Optimal? |
|---|---|---|
| Merge Sort | \(O(n \log n)\) | Yes! |
| Heap Sort | \(O(n \log n)\) | Yes! |
| Quick Sort | \(O(n^2)\) | No (but avg is optimal) |
| Insertion Sort | \(O(n^2)\) | No |
| Selection Sort | \(O(n^2)\) | No |
Merge sort achieves the theoretical limit.
The lower bound applies to comparison-based sorts.
If we know something about the input, we can do better:
| Algorithm | Constraint | Time |
|---|---|---|
| Counting Sort | Integers in \([0, k]\) | \(O(n + k)\) |
| Radix Sort | Fixed-width integers | \(O(d \cdot n)\) |
In practice: Just use Python’s sorted() (Timsort, \(O(n \log n)\)).
You wake up in a maze. Every room has a number. Some rooms have multiple exits.
Question: How do you explore systematically to find the way out?

Write down everything you noticed:
Programmatic realization of a ________________.
Stack functions:
push(item)pop() \(\rightarrow\) itemList functions:
append(item)pop() \(\rightarrow\) item
“Dynamic Array Diversion”