• 沒有找到結果。

Description of quicksort

在文檔中 ALGORITHMS INTRODUCTION TO (頁 191-195)

Third Edition

7.1 Description of quicksort

Quicksort, like merge sort, applies 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-rays AŒp : : q  1 and AŒq C 1 : : r such that each element of AŒp : : q  1 is less than or equal to AŒq, which is, in turn, less than or equal to each element of AŒq C 1 : : r. Compute the index q as part of this partitioning procedure.

Conquer: Sort the two subarrays AŒp : : q  1 and AŒq C 1 : : r by recursive calls to quicksort.

Combine: Because the subarrays are already sorted, no work is needed to combine them: the entire array AŒp : : r is now sorted.

The following procedure implements quicksort:

QUICKSORT.A; p; r/

1 ifp < r

2 q D PARTITION.A; p; r/

3 QUICKSORT.A; p; q  1/

4 QUICKSORT.A; q C 1; r/

To sort an entire array A, the initial call is QUICKSORT.A; 1; A:length/.

Partitioning the array

The key to the algorithm is the PARTITIONprocedure, which rearranges the subar-ray AŒp : : r in place.

PARTITION.A; p; r/

1 x D AŒr

2 i D p  1

3 forj D p to r  1 4 ifAŒj   x

5 i D i C 1

6 exchange AŒi  with AŒj  7 exchange AŒi C 1 with AŒr

8 returni C 1

Figure 7.1 shows how PARTITION works on an 8-element array. PARTITION

always selects an element x D AŒr as a pivot element around which to partition the subarray AŒp : : r. As the procedure runs, it partitions the array into four (possibly empty) regions. At the start of each iteration of the for loop in lines 3–6, the regions satisfy certain properties, shown in Figure 7.2. We state these properties 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 C 1  k  j  1, then AŒk > x.

3. If k D r, then AŒk D x.

2 8 7 1 3 5 6 4

Figure 7.1 The operation of PARTITIONon a sample array. Array entry AŒr becomes the pivot element x. Lightly shaded array elements are all in the first partition with values no greater than x.

Heavily shaded elements are in the second partition with values greater than x. The unshaded el-ements have not yet been put in one of the first two partitions, and the final white element is the pivot x. (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 itself” and put in the partition of smaller values. (c)–(d) The values 8 and 7 are added to the partition of larger values. (e) The values 1 and 8 are swapped, and the smaller partition grows. (f) The values 3 and 7 are swapped, and the smaller partition grows. (g)–(h) The larger partition grows to include 5 and 6, and the loop terminates. (i) In lines 7–8, the pivot element is swapped so that it lies between the two partitions.

The indices between j and r  1 are not covered by any of the three cases, and the values in these entries have no particular relationship to the pivot x.

We need to show that this loop invariant is true prior to the first iteration, that each iteration of the loop maintains the invariant, and that the invariant provides a useful property to show correctness when the loop terminates.

≤ x > x unrestricted x

p i j r

Figure 7.2 The four regions maintained by the procedure PARTITIONon a subarray AŒp : : r. The values in AŒp : : i  are all less than or equal to x, the values in AŒi C 1 : : j  1 are all greater than x, and AŒr D x. The subarray AŒj : : r  1 can take on any values.

Initialization: Prior to the first iteration of the loop, i D p  1 and j D p. Be-cause no values lie between p and i and no values lie between i C 1 and j  1, the first two conditions of the loop invariant are trivially satisfied. The assign-ment in line 1 satisfies 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 AŒj  > x;

the only action in the loop is to increment j . After j is incremented, condition 2 holds for AŒj  1 and all other entries remain unchanged. Figure 7.3(b) shows what happens when AŒj   x; the loop increments i , swaps AŒi  and AŒj , and then increments j . Because of the swap, we now have that AŒi   x, and condition 1 is 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 D 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 array 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 PARTITIONfinish up by swapping the pivot element with the leftmost element greater than x, 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 satisfies the specifications given for the divide step. In fact, it satisfies a slightly stronger condition: after line 2 of QUICKSORT, AŒq is strictly less than every element of AŒq C 1 : : r.

The running time of PARTITION on the subarray AŒp : : r is ‚.n/, where n D r  p C 1 (see Exercise 7.1-3).

Exercises

7.1-1

Using Figure 7.1 as a model, illustrate the operation of PARTITION on the array A D h13; 19; 9; 5; 12; 8; 7; 4; 21; 2; 6; 11i.

≤ x > x

x

p i j r

> x (a)

≤ x > x

x

p i j r

≤ x > x

x

p i j r

≤ x (b)

≤ x > x

x

p i j r

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

7.1-2

What value of q does PARTITION return when all elements in the array AŒp : : r

have the same value? Modify PARTITION so that q D b.p C r/=2c when all elements in the array AŒp : : r have the same value.

7.1-3

Give a brief argument that the running time of PARTITIONon a subarray of size n is ‚.n/.

7.1-4

How would you modify QUICKSORTto sort into nonincreasing order?

在文檔中 ALGORITHMS INTRODUCTION TO (頁 191-195)