Quicksort
Quicksort
You can enforce the assumption that the values in an array are distinct at the cost of
additional space and only constant overhead in running time by converting each input value to
an ordered pair with if or if and .
There are also more practical variants of quicksort that work well when elements are not distinct.
7.1 Description of quicksort 183
Q UICKSORT
1 if
2 // Partition the subarray around the pivot, which ends up in .
3 PARTITION
4 Q UICKSORT // recursively sort the low side
5 Q UICKSORT // recursively sort the high side
PARTITION
1 // the pivot
2 // highest index into the low side
3 for to // process each element other than the pivot
4 if // does this element belong on the low side?
5 // index of a new slot in the low side
6 exchange with // put this element there
7 exchange with // pivot goes just to the right of the low side
8 return // new index of the pivot
At the beginning of each iteration of the loop of lines 336, for any array
index , the following conditions hold:
1. if , then (the tan region of Figure 7.2);
2. if , then (the blue region);
3. if , then (the yellow region).
We need to show that this loop invariant is true prior to the ûrst iteration, that
each iteration of the loop maintains the invariant, that the loop terminates, and that
correctness follows from the invariant when the loop terminates.
Initialization: Prior to the ûrst iteration of the loop, we have and
. Because no values lie between and and no values lie between
and , the ûrst two conditions of the loop invariant are trivially satisûed.
The assignment in line 1 satisûes the third condition.
Maintenance: As Figure 7.3 shows, we consider two cases, depending on the
outcome of the test in line 4. Figure 7.3(a) shows what happens when :
the only action in the loop is to increment . After has been incremented, the
second condition holds for and all other entries remain unchanged.
Figure 7.3(b) shows what happens when : the loop increments ,
swaps and , and then increments . Because of the swap, we now
have that , and condition is satisûed. Similarly, we also have that
, since the item that was swapped into is, by the loop
invariant, greater than .
Termination: Since the loop makes exactly iterations, it terminates, where-
upon . At that point, the unexamined subarray is empty, and
every entry in the array belongs to one of the other three sets described by the
invariant. Thus, the values in the array have been partitioned into three sets:
those less than or equal to (the low side), those greater than (the high side),
and a singleton set containing (the pivot).
7.1 Description of quicksort 185
i p,j r
(a) 2 8 7 1 3 5 6 4
p,i j r
(b) 2 8 7 1 3 5 6 4
p,i j r
(c) 2 8 7 1 3 5 6 4
p,i j r
(d) 2 8 7 1 3 5 6 4
p i j r
(e) 2 1 7 8 3 5 6 4
p i j r
(f) 2 1 3 8 7 5 6 4
p i j r
(g) 2 1 3 8 7 5 6 4
p i r
(h) 2 1 3 8 7 5 6 4
p i r
(i) 2 1 3 4 7 5 6 8
Figure 7.1 The operation of PARTITION on a sample array. Array entry becomes the pivot
element . Tan array elements all belong to the low side of the partition, with values at most .
Blue elements belong to the high side, with values greater than . White elements have not yet been
put into either side of the partition, and the yellow element is the pivot . (a) The initial array and
variable settings. None of the elements have been placed into either side of the partition. (b) The
value is <swapped with itself= and put into the low side. (c)–(d) The values and are placed into
to high side. (e) The values and are swapped, and the low side grows. (f) The values and are
swapped, and the low side grows. (g)–(h) The high side of the partition grows to include and ,
and the loop terminates. (i) Line 7 swaps the pivot element so that it lies between the two sides of
the partition, and line 8 returns the pivot’s new index.
The ûnal two lines of PARTITION ûnish up by swapping the pivot with the left-
most element greater than , thereby moving the pivot into its correct place in
the partitioned array, and then returning the pivot’s new index. The output of
PARTITION now satisûes the speciûcations given for the divide step. In fact, it
satisûes a slightly stronger condition: after line 3 of Q UICKSORT, is strictly
less than every element of .
186 Chapter 7 Quicksort
p i j r
x
≤x >x unknown
Figure 7.2 The four regions maintained by the procedure P ARTITION on a subarray . The
tan values in are all less than or equal to , the blue values in are all greater
than , the white values in have unknown relationships to , and .
p i j r
(a) >x x
≤x >x
p i j r
x
≤x >x
p i j r
(b) ≤x x
≤x >x
p i j r
x
≤x >x
Figure 7.3 The two cases for one iteration of procedure P ARTITION . (a) If , the only
action is to increment , which maintains the loop invariant. (b) If , index is incremented,
and are swapped, and then is incremented. Again, the loop invariant is maintained.
Exercise 7.1-3 asks you to show that the running time of PARTITION on a sub-
array of elements is .
Exercises
7.1-1
Using Figure 7.1 as a model, illustrate the operation of PARTITION on the array
.