اموزش الگوریتم کوییک سورت!!
CHAPTER 8: QUICKSORT
8.1 Description of quicksort
Conquer: The two subarrays A[p . . q] and A[q + 1 . . r] are sorted by recursive calls to quicksort.
The following procedure implements quicksort.
QUICKSORT(A,p,r)
1 if p < r
2 then qPARTITION(A,p,r)
3 QUICKSORT(A,p,q)
4 QUICKSORT(A,q + 1,r)
To sort an entire array A, the initial call is QUICKSORT(A, 1, length[A]).
Partitioning the array
PARTITION(A,p,r)
1 xA[p]
2 ip - 1
3 jr + 1
4 while TRUE
5 do repeat jj - 1
6 until A[j]x
7 repeat ii + 1
8 until A[i]x
9 if i < j
10 then exchange A[i]A[j]
11 else return j
Figure 8.1 The operation of PARTITION
on a sample array. Lightly shaded array elements have been placed into
the correct partitions, and heavily shaded elements are not yet in
their partitions. (a) The input array, with the initial values of i and
j just off the left and right ends of the array. We partition around x
= A[p] = 5. (b) The positions of i and j at line 9 of the first
iteration of the while loop. (c) The result of exchanging the elements
pointed to by i and j in line 10. (d) The positions of i and j at line
9 of the second iteration of the while loop. (e) The positions of i and
j at line 9 of the third and last iteration of the while loop. The
procedure terminates because i
j, and the value q = j is returned. Array elements up to and including
A[j] are less than or equal to x = 5, and array elements after A[j] are
greater than or equal to x = 5.
Exercises
What value of q does PARTITION return when all elements in the array A[p . . r] have the same value?
Give a brief argument that the running time of PARTITION on a subarray of size n is
(n).
How would you modify QUICKSORT to sort in nonincreasing order?
8.2 Performance of quicksort
Worst-case partitioning
T(n) = T(n - 1) +(n).
To evaluate this recurrence, we observe that T(1) =
(1) and then iterate:
Figure 8.2 A recursion tree for QUICKSORT in which the PARTITION procedure always puts only a single element on one side of the partition (the worst case). The resulting running time is
(n2).
Best-case partitioning
T(n) = 2T(n/2) +(n),
Balanced partitioning
T(n) = T(9n/10) + T(n/10) + n
Figure 8.3 A recursion tree for QUICKSORT in which PARTITION always balances the two sides of the partition equally (the best case). The resulting running time is
(n lg n).
Figure 8.4 A recursion tree for QUICKSORT in which PARTITION always produces a 9-to-1 split, yielding a running time of
(n lg n).
Intuition for the average case
Figure 8.5 (a) Two levels of a recursion tree for quicksort. The partitioning at the root costs n and produces a "bad" split: two subarrays of sizes 1 and n - 1. The partitioning of the subarray of size n - 1 costs n - 1 and produces a "good" split: two subarrays of size (n - 1)/2. (b) A single level of a recursion tree that is worse than the combined levels in (a), yet very well balanced.
Exercises
Show that the running time of QUICKSORT is
(n2) when the array A is sorted in nonincreasing order.
8.3 Randomized versions of quicksort
RANDOMIZED-PARTITION(A,p,r)
1 iRANDOM(p,r)
2 exchange A[p]A[i]
3 return PARTITION(A,p,r)
We now make the new quicksort call RANDOMIZED-PARTITION in place of PARTITION:
RANDOMIZED-QUICKSORT(A,p,r)
1 if p < r
2 then qRANDOMIZED-PARTITION(A,p,r)
3 RANDOMIZED-QUICKSORT(A,p,q)
4 RANDOMIZED-QUICKSORT(A,q + 1,r)
We analyze this algorithm in the next section.
Exercises
8.4 Analysis of quicksort
8.4.1 Worst-case analysis
(8.1)
Continuing with our bounding of T(n), we obtain
T(n)cn2 - 2c(n - 1) +
(n)
cn2 ,
8.4.2 Average-case analysis
Analysis of partitioning
A recurence for the average case
(8.2)
(8.3)
(8.4)
Solving the recurrence
We show below that the summation in the last line can be bounded by
(8.5)
Tight bounds on the key summation
It remains to prove the bound (8.5) on the summation
Since each term is at most n lg n, we have the bound
if n
2. This is the bound (8.5).
Exercises
Show that quicksort's best-case running time is
(n1gn).
Show that q2 + (n - q)2 achieves a maximum over q = 1, 2, . . . , n - 1 when q = 1 or q = n - 1.
Show that RANDOMIZED-QUICKSORT's expected running time is
(n 1g n).
Problems
Give a careful argument that the procedure PARTITION in Section 8.1 is correct. Prove the following:
a. The indices i and j never reference an element of A outside the interval [p . . r].
b. The index j is not equal to r when PARTITION terminates (so that the split is always nontrivial).
8-2 Lomuto's partitioning algorithm
LOMUTO-PARTITION(A, p, r)
1 xA[r]
2 ip - 1
3 for jp to r
4 do if A[j]x
5 then ii + 1
6 exchange A[i]A[j]
7 if i < r
8 then return i
9 else return i - 1
a. Argue that LOMUTO-PARTITION is correct.
c. Argue that LOMUTO-PARTITION, like PARTITION, runs in
(n) time on an n-element subarray.
Professors Howard, Fine, and Howard have proposed the following "elegan" sorting algorithm:
QUICKSORT'(A,p,r)
1 while p < r
2 doPartition and sort left subarray
3 qPARTITION(A,p,r)
4 QUICKSORT'(A,p,q)
5 pq + 1
a. Argue that QUICKSORT'(A, 1, length[A]) correctly sorts the array A.
b. Describe a scenario in which the stack depth of QUICKSORT' is
(n) on an n-element input array.
c. Modify the code for QUICKSORT' so that the worst-case stack depth is
(1g n).
Chapter notes
PARTITION(A,p,r)
x
A[j]
13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21
.
is the arithmetic series (3.2). Figure 8.2 shows a recursion tree for
this worst-case execution of quicksort. (See Section 4.2 for a
discussion of recursion trees.)



to 



. We can thus restate recurrence (8.2) as




dominates 

for the solution of the recurrence to work out.


.
Partition and sort left subarray
(n + 1)/2
], the median of A[1 . . n], compared to the ordinary implementation? Assume that n
, and give the limiting ratio of these probabilities.