0% found this document useful (0 votes)
33 views

4.1. Quick Sort

Uploaded by

Mithun
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

4.1. Quick Sort

Uploaded by

Mithun
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

7 Quicksort

Quicksort is a sorting algorithm whose worst-case running time is (n) on


input array of n numbers. In spite of this slow an
is often the best practical choice for sorting worst-case running time, quicksort
because it is remarkably efficient on
the average: its expected running time is O(n lg n), and the
in the (nlg n) notation are quite small. It also has the constant factors hidden
advantage of sorting in
place (see page 16), and works well even in virtual memory environnments.
Section 7.1 describes the algorithm and an important subroutine used by quick
sort for partitioning. Because the behavior of quicksort is complex, we start with
an intuitive discussion of its performance in Section 7.2 and
postpone its precise
analysis to the end of the chapter. Section 7.3 presents a version of quicksort that
uses random sampling. This algorithm has a good average-case running time, and
no particular input elicits its worst-case behavior. The randomized algorithm is
analyzed in Section 7.4, where it is shown to run in O(n) time in the worst case
and in O(n lg n) time on average.

7.1 Desceription of quicksort

Quicksort, like merge sort, is based on the divide-and-conquer paradigm introduced


in Section 2.3.1. Here is the three-step divide-and-conquer process for sorting a
typical subarray A[p ..r].
Divide: Partition (rearrange) the array A[p..r] into two (possibly empty) subar
raysA[p..q- 1] and A[g +1.]such that each element of A[p.. q-1 is
less than or equal to ALg], which is, in turn, less than or equal to each element
of Alg +1..r]. Compute the index qas part of this partitioning procedure.
Conquer: Sort the two subarrays Alp ..4-1|and Alq +1..r]by recursive calls
toquicksort.
Combine: Since the subarrays are sorted in place, no work is needed to combine
them: the entire array A[p..r] is now sorted.
146 Chapter 7 Quicksort

The following procedure implements quicksort.


QUICKSORT(A, p, r)
1 ifp <r
2 then q - PARTITION(A, p, r)
3 QUICKSORT(4, p, q - 1)
4 QUICKSORT(A, q+ 1,r)
Tosort an entire array A, the initial call is QUICKSORT(A, 1, lengthËA).

Partitioning the array


The key to the algorithm is the PARTITION procedure, which rearranges the suba:
ray A[p..r] in place.
PARTITION (A, p, r)
1 x+A[r]
2 ip-1
3 for j ptor-1
4 do if ALj]sx
5 then i -i+1
6 exchange A[i] > Aj]
7 exchange A[i + 1] > A[r]
8 return i+ 1

Figure 7.1 shows the operation of PARTITION on an 8-element array. PARTITION


always selects an element x = A[r] as a pivot element around which to partition
the subarray Alp..r]. As the procedure runs, the array is partitioned into fou
(possibly empty) regions. At the start of each iteration of the for loop in lines 3,
each region satisfies certain properties, which we can state as a loop invariant:
At the beginning of each iteration of the loop of lines 3-6, for any array
index k,
1. If p<k<i, then A[k] <x.
2. If i+ 1 <k<j- 1,then A[k] > x.
3. If k =r, then A[k] =x.
Figure 7.2 summarizes this structure. The indices between j and r - l are
particular
covered by any of the three cases, and the values in these entries have no
relationship to the pivot x.
We need to show that this loop invariant is true prior to the first iteration,
provides
each iteration of the loop maintains the invariant, and that the invariant
useful property to show correctness when the loop terminates.
7.1 Description of quicksort 147

i pj
(a) 28713564
(b) 28713 564

(c) 2 7 ||356 4

(d) 2 1 3 5 64

pi
(e) 2 1 356 4

() 2 13 64|

(g) |2 13 64
p
(h) 2| 1|3
p
(i) 2 13 4

Figure 7.1 The operation of PARTITION on a sample array. Lightly shaded array elements are all in
the first partition with values no greater thanx. Heavily shaded elements are in the second partition
with values greater than x. The unshaded elements have not yet been put in one of the first two
partitions, and the final white element is the pivot. (a) The initial array and variable settings. None of
the elements have been placed in either of the first two partitions. (b) The value 2 is "swapped with
partition
itself" and put in the partition of smaller values. (c)<d) The values 8and 7are added to the
grows. () The values
of larger values. (e) The values 1 and 8 are swapped, and the smaller partition include
grows to
3and 8 are swapped, and the smaller partition grows. (g-(h) The larger partition
lines 7-8, the pivot element is swapped so that it lies between
5and 6 and the loop terminates. (i) In
the two partitions.

Initialization: Prior to the first iteration of the loop, i p-1, and j = p. There
i + 1 and j - l, so the
are no values between p and i, and no values between
The assignment
first two conditions of the loop invariant are trivially satisfied.
condition.
in line 1l satisfies the third
consider, depending
Maintenance: As Figure 7.3shows, there are two cases to what happens when
7.5(a) shows
on the outcome of the test in line 4. igure
148 Chapter 7 Quicksort

unrestricted

Figure 7.2 The four regions maintained by the procedure PARTITION on a subarray A[p
values in A[p..i) are all lessthan or equal to x, the values in A[i +1..j - 1] are all greater. r).than
Thex,
and A[r] =x. The values in Aj..r - 1] can take on any values.

AU] > x; the only action in the loop is to increment j. After i is incr
mented, condition 2 holds for A[j 1]and all other entries remain unchanged
Figure 7.3(b) shows what happens when A[j] s x; iis incremented, Ail
and ALj] are swapped, and then j is incremented. Because of the Swap, we
now have that A[i]<x, and condition lis satisfied. Similarly, we also have
that A[j- 1] > x, since the item that was swapped into A[j - 1] is, by the
loop invariant, greater than x.
Termination: At termination,j=r. Therefore, every entry in the array is in one
of the three sets described by the invariant, and we have partitioned the values
in the aray into three sets: those less than or equal to x, those greater than x,
and a singleton set containing x.
The final two lines of PARTITION Move the pivot element into its place in the
middle of the array by swapping it with the leftmost element that is greater than X.
The output of PARTITION now satisfies the specifications given for the divide step.
The running time of PARTITION on the subarray A[p..r] is (n), wher
n=r-p+1(see Exercise 7.1-3).

Exercises
7.1-1
Using Figure 7.1 as a model, illustrate the operation of PARTITION onthe array
A= (13, 19,9, 5, 12, 8,7, 4, 11, 2,
6,21).
7.1-2
What value of g does Alp..l
PARTITION return when all elements in the arTay
have the same value? Modify (p+r)/2 when.all elements
in the array A[p..r]have the PARTITION that
SO q=
same value.
7.1-3 n
ofsize
Give a brief argument that the time of PARTITION on asubarray
is (n). running
7.2 Performance of quicksort 149

(a)

>

(b)

>X

Figure 7.3 The two cases for one iteration of procedure PARTITION. (a) If Aj] > x, the oniy
action is to increment i, which maintains the loop invariant. (b) If Ai] <x, index i is incremented,
A[i] and AU]are swapped, and then j is incremented. Again, the loop invariant is maintained.

7.1-4
How would you modify QUICKSORT to sort into nonincreasing order?

7.2 Performance of quicksort

The running time of quicksort depends on whether the partitioning is balanced or


unbalanced, and this in turn depends on which elements are used for partitioning.
If the partitioning is balancd, the algorithm runs asymptotically as fast as merge
sort, If the partitioning is unbalanced, however, it can run asymptotically as slowly
quicksort
as insertion sort. In this section, we shall intormally investigate how
partitioning.
performs under the assumptions of balanced versus unbalanced

Worst-case partitioning
routine nro.
The worst-case behavior for quicksort occurs when the partitioning
Oelements. (This clains
duces one subproblem withn - lelements and one with partitioning arises
is proved in Section 7.4.1.) Let us asSume that this unbalanced
time. Since the recursive l
in each recursive call. The partitioning costs (n)
150
Chapter 7 Qicksort

on an array of size 0just returns, T(0) = (1), and the recurrence for
time is the running
T(n) = T(n - 1) + T(0) + (n)
= T(n - 1) + O(n)
Intuitively, if we sum the costs incurred at each level of the recursion,
an arithmetic series (equation (A.2), which evaluates to On2).
Indeed,
straightforward to use the substitution method to prove that the recurrence
T(n 1) + O(n) has the solution T(n) = O(n').(See Exercise 7.2-1.) T(n)=
Thus, if the partitioning is maximally unbalanced at every recursive level of tha
algorithm, the running time is 0(n'). Therefore the worst-case running time of
quicksort is no better than that of insertion sort. Moreover, the O(n') running time
occurs when the input array is already completely sorted-a common situation in
which insertion sort runs in O
(n) time.

Best-case partitioning
In the most even possible split, PARTITION produces two subproblems, each of
size no more than n/2, since one is of size n/2] and one of size [n/2]-1. In this
case, quicksort runs much faster. The recurrence for the running time is then
T(n) < 2T (n/2) + (n),
which by case 2 of the master theorem (Theorem 4.1) has the solution T(n) =
O(nlgn). Thus, the equal balancing of the two sides of the partition at every level
of the recursion produces an asymptotically faster algorithm.

Balanced partitioning
The average-case running time of quicksort is much closerto the best case thanto
the worst case, as the analyses in Section 7.4 will show. The key to understand
ing why is to understand how the balance of the partitioningis reflectedinthe
recurrence that describes the running time. 9-(0-!
a
Suppose, for example, that the partitioning algorithm always producesobtain
the
proportional split, which at first blush seems quite unbalanced. We then
recurTence
T(n) <T (9n/10) +
T(n/10) + cn constant
on the running time of the
where we have explicitly included
hidden in the O(n) term.quicksort,
recurrence
recursion tree for this
Figure 7.4 shows the
condition isreached
Notice that every level of the tree has cost cn, until a boundary
at depth logo = quicksort
(lg n), and then the levels have cost at mostcsot i
cursion terminates at depth log10/9 n= (lg n). The total cost of

You might also like