Home

[This page is auto-generated; please prefer to read the article’s PDF Form.]



[Prev]   [Up]   

Constructing an Adverse Input

For an input array a of n elements, algorithm A may require a varying number of comparisons depending upon the initial order of the elements. We are interested in the maximum among these number of comparisons, which can be called the number of comparisons in the “worst-case”, and denoted Cw.

Since we do not know how exactly A works, it is impossible to construct its worst-case input. What we will instead do is construct an adverse input and count the least number of comparisons Cd which A would do for that input. Since we must have Cw Cd, Cd will give us a lower-bound on Cw.

To construct an adverse input, we will take some array a with its keys uninitialized and modify the comparison function f as follows. f will keep track of the set S. To compare ai and aj, instead of using their keys, it will check how many permutations in S have ai occurring before aj (the subset P defined earlier). If it finds |P|≥|Q|, it will respond with output “ai < aj” (true), otherwise it will respond with “ai aj” (false). This will result in the algorithm A always left with the larger of the two subsets P and Q, hence more number of candidate permutations to work with. As mentioned earlier, this larger subset must have cardinality at least |S|2.

Since this modified function f does not use the keys, throughout the execution of algorithm A the keys would remain unused; that’s why we could leave them uninitialized. Now, how can we really initialize the keys of the input array a, so that A would execute in exactly the same manner, but with the original comparison function f? In other words, how can we construct such adverse input?

For that, we will use the sorted output permutation from above execution of A. The keys of input array a can be initialized such that their sorted order would be the same as this permutation. For example, with n = 5, if the output permutation obtained above is (a3,a0,a2,a4,a1), the keys of a should be chosen such that a3 < a0 < a2 < a4 < a1. For integer keys with f based on their numerical order, this can be done, for example, by choosing the keys for a3,a0,a2,a4 and a1 as 1,2,3,4 and 5 respectively.

We know that the output permutation must be consistent with the result of all the comparisons made in above execution of A. So, the adverse input constructed using its order must cause exactly the same comparison results and same execution flow of A.

Having constructed an adverse input, let us now count Cd. After each comparison, A is left with the subset having cardinality at least |S|2. Since the cardinality of S is n! initially, after k comparisons, it must be at least (n!)2k. So algorithm A will require at least Cd comparisons till the cardinality becomes 1, where:

     n!--≤ 1
     2Cd
⇔     Cd ≥ log2(n!)

And since Cw Cd, we have:

Cw ≥ log2(n!)
(1)

It can be proved that log2(n!) belongs to the set Θ(nlog2 n) (see [1]: chapter 3 section “Factorials”, and exercise 8.1-2). So we conclude that, any comparison-based sorting algorithm will do at least log2(n!) (Θ(nlog2 n)) comparisons for its worst-case input.

References

[1]   T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein. Introduction to Algorithms, Third Edition. The MIT Press (2009).

[Prev]   [Up]