



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Partition Algorithm, Quicksort, Quick Sort Example, Trace of partitioning algorithm, Analysis of Quicksort, Worst Case Analysis of Quick Sort, Recurrences are the key points in this study notes file.
Typology: Study notes
1 / 5
This page cannot be seen from the preview
Don't miss anything!




Our next sorting algorithm is Quicksort. It is one of the fastest sorting algorithms known and is the method of choice in most sorting libraries. Quicksort is based on the divide and conquer strategy. Here is the algorithm:
1 if (r > p) 2 then 3 I ← a random index from [p..r] 4 swap A[i] with A[p] 5 q ← PARTITION(A, p, r) 6 QUICKSORT(A, p, q - 1) 7 QUICKSORT(A, q + 1, r)
4.3.1 Partition Algorithm Recall that the partition algorithm partitions the array A[p..r] into three sub arrays about a pivot element x. A[p..q - 1] whose elements are less than or equal to x, A[q] = x, A[q + 1..r] whose elements are greater than x. We will choose the first element of the array as the pivot, i.e. x = A[p]. If a different rule is used for selecting the pivot, we can swap the chosen element with the first element. We will choose the pivot randomly.
The algorithm works by maintaining the following invariant condition. A[p] = x is the pivot value. A[p..q - 1] contains elements that are less than x, A[q + 1..s - 1] contains elements that are greater than or equal to x A[s..r] contains elements whose values are currently unknown.
1 x ← A[p] 2 q ← p 3 for s ← p + 1 to r 4 do if (A[s] < x) 5 then q ← q + 1 6 swap A[q] with A[s] 7 swap A[p] with A[q] 8 return q
Figure 4.4 shows the execution trace partition algorithm.
r Figure 4.4: Trace of partitioning algorithm
4.3.2 Quick Sort Example The Figure 4.5 trace out the quick sort algorithm. The first partition is done using the last element, 10 , of the array. The left portion are then partitioned about 5 while the right portion is partitioned about 13. Notice that 10 is now at its final position in the eventual sorted order. The process repeats as the algorithm recursively partitions the array eventually sorting it.
5 13 10 1 2 4 3 8 6 7 ⇓
⇓ 3 4 7 6 8 9 12 17 14 15 11 13 10 16 5
⇓
It is interesting to note (but not surprising) that the pivots form a binary search tree. This is illustrated in Figure 4.6.
Figure 4.6: Quicksort BST
4.3.3 Analysis of Quicksort The running time of quicksort depends heavily on the selection of the pivot. If the rank of the pivot is very large or very small then the partition (BST) will be unbalanced. Since the pivot is chosen randomly in our algorithm, the expected running time is O(n log n).
The worst case time, however, is O(n 2 ). Luckily, this happens rarely.
4.3.4 Worst Case Analysis of Quick Sort Let’s begin by considering the worst-case performance, because it is easier than the average case. Since this is a recursive program, it is natural to use a recurrence to describe its running time. But unlike MergeSort, where we had control over the sizes of the recursive calls, here we do not. It depends on how the pivot is chosen. Suppose that we are sorting an array of size n, A[1 : n], and further suppose that the pivot that we select is of rank q, for some q in the range 1 to n. It takes Θ(n) time to do the partitioning and other overhead, and we make two recursive calls. The first is to the subarray A[1 : q - 1] which has q - 1 elements, and the other is to the subarray A[q + 1 : n] which has n - q elements. So if we ignore the Θ(n) (as usual) we get the recurrence:
T(n) = T(q - 1) + T(n - q) + n
This depends on the value of q. To get the worst case, we maximize over all possible values of q. Putting is together, we get the recurrence
Recurrences that have max’s and min’s embedded in them are very messy to solve. The key is determining which value of q gives the maximum. (A rule of thumb of algorithm analysis is that the worst cases tends to happen either at the extremes or in the middle. So I would plug in the value q = 1, q = n, and q = n/2 and work each out.) In this case, the worst case happens at either of the extremes. If we expand the recurrence for q = 1, we get: T(n) ≤ T(0) + T(n - 1) + n = 1 + T(n - 1) + n = T(n - 1) + (n + 1) = T(n - 2) + n + (n + 1) = T(n - 3) + (n - 1) + n + (n + 1) = T(n - 4) + (n - 2) + (n - 1) + n + (n + 1) = T(n - k) +
For the basis T(1) = 1 we set k = n - 1 and get
= 1 + (3 + 4 + 5 + · · · + (n - 1) + n + (n + 1))