Lowerbound of Sorting

In terms of time complexity, we have seen two types of sorting algorithms:

You might wonder why all fast sorting algorithms run in \(O(n\log n)\) time.

Now let’s answer these questions. The short answer is: that’s not a coincidence, and \(O(n\log n)\) time is indeed the fastest we can get in terms of internal comparison-based sorting (although external sorting using disk space can get even faster, but that’s beyond the scope of this course). This is because you need at least \(\sim n \log n\) comparisons to figure out the exact ordering for \(n\) numbers.

To see why this is the case, consider the number of all possible orderings for \(n\) distinct numbers, which is \(n!\). A priori you don’t know which ordering is the sorted order, and the job of a sorting algorithm is to use comparisons to reduce the number of possible orderings down to 1. Each comparison (such as \(a_1 ?\ a_2\)) would halve the number of (remaining) possibilities (there are exactly \(\frac{n!}{2}\) orders where \(a_1 < a_2\) and another \(\frac{n!}{2}\) where \(a_1 > a_2\)). Let’s say \(a_1 < a_2\), then we compare \(a_1 ?\ a_3\), whose result would further reduce the remaining \(\frac{n!}{2}\) possible orderings by half.

So you can draw a decision tree like this (like recursion trees we have seen so far):

                a_1 ? a_2             n! possibile orderings
            < /           \ >
             /             \
        a_1 ? a_3       a_2 ? a_3     n!/2 possbile orderings

          ...              ...

How many levels (or comparisons) do you need to reach a unique ordering?

\[h = \log (n!)\]

Now let’s simplify this \(h\). It’s obvious that \((\frac{n}{2})^\frac{n}{2} < n! < n^n\), which can be shown geometrically:

   |****--->| n
   |****--> | n-1
   |****->  | ...
   |****>   | n/2
   |--->    | ...
   |-->     | ...
   |->      | 2
   +>-------+ 1

In complexity analysis, we say the lowerbound of sorting is \(\Omega (n \log n)\), because Big-\(O\) is for upperbound, Big-\(\Omega\) is for lowerbound, and Big-\(\Theta\) for precise bound: \(f(n) = \Theta(g(n))\) if and only if \(f(n) = O(g(n))\) and \(f(n) = \Omega(g(n))\). See Wikipedia for details.