Download presentation
Presentation is loading. Please wait.
Published byVictor Moore Modified over 8 years ago
1
Data Structures and Algorithms (AT70.02) Comp. Sc. and Inf. Mgmt. Asian Institute of Technology Instructor: Prof. Sumanta Guha Slide Sources: CLRS “Intro. To Algorithms” book website (copyright McGraw Hill) adapted and supplemented
2
CLRS “Intro. To Algorithms” Ch. 7: Quicksort
4
pivot From i +1 to j is a window of elements > A[r]. The cursor j moves right one step at a time. If the cursor j “discovers” an element ≤ A[r], then this element is swapped with the front element of the window, effectively moving the window right one step; if it discovers an element > A[r], then the window simply becomes longer one unit.
5
Do Ex. 7.1-1.
6
Performance of Quicksort Worst-case partitioning: one subproblem of size n-1, other 0. Time: (n 2 ). Why? Best-case partitioning: each subproblem of size at most n/2. Time: (nlog n). Why? Balanced partitioning: even if each subproblem size is at least a constant proportion of the original problem the running time is (nlog n).
9
Expected Running Time of RANDOMIZED-QUICKSORT Lemma 7.1: Let X be the number of comparisons performed in line 4 of PARTITION over the entire execution of QUICKSORT (or RANDOMIZED-QUICKSORT ) on an n-element array. Then the running time of QUICKSORT (or RANDOMIZED-QUICKSORT ) is O(n +X). Proof: There are at most n calls to PARTITION (Why? Because the pivot is dropped from future recursive calls.). Each call to PARTITION does constant work and executes the for loop some number of iterations. Therefore, the total work done is O(n) + the total number of iterations of the for loop over the entire execution of QUICKSORT. However, each iteration of the for loop performs the comparison of line 4 exactly once. Conclusion follows.
10
Rename the array z 1, z 2, …, z n, where z 1 ≤ z 2 ≤ … ≤ z n Let the indicator random variable X ij = I{z i is compared to z j }. Then X = ∑ i=1..n-1 ∑ j=i+1..n X ij Therefore, E[X] = E[ ∑ i=1..n-1 ∑ j=i+1..n X ij ] = ∑ i=1..n-1 ∑ j=i+1..n Pr{z i is compared to z j } Now, z i and z j are compared iff the first element to be chosen from Z ij = [z i, z i+1, …, z j ] as pivot is either z i or z j. Prior to the point when an element of Z ij is chosen as pivot, all of Z ij is in the same partition. Because pivots are chosen randomly any element of Z ij is equally likely to be the first chosen as pivot. We conclude: Pr{z i is compared to z j } = 2 / (j-i+1) Therefore, E[X] = ∑ i=1..n-1 ∑ j=i+1..n 2 / (j-i+1) = ∑ i=1..n-1 ∑ k=1..n-i 2 / (k+1) ≤ ∑ i=1..n-1 ∑ k=1..n-1 2/(k+1) < ∑ i=1..n-1 ∑ k=1..n 2/k = ∑ i=1..n-1 O(log n) = O(nlog n) where k = j-i
11
Hoare’s Original Partitioning Strategy Do Prob. 7-1a
12
Tail Recursion int bsTR(int Low, int High, double X, double A[]) { int Mid; if (Low > High) return (-1); //search failed Mid = (Low + High)/2; if (A[Mid] < X) return ( bsTR(Mid + 1, High, X, A) ); // tail-recursive call else if (X < A[Mid]) return ( bsTR(Low, Mid - 1, X, A) ); // tail-recursive call else return (Mid); // X has been located } int bsNonTR(int Low, int High, double X, double A[]) { int Mid; start: if (Low > High) return (-1); //search failed Mid = (Low + High)/2; if (A[Mid] < X) { Low = Mid + 1; goto start; } else if (X < A[Mid]) { High = Mid - 1; goto start; } else return (Mid); // X has been located } Tail recursive binary search A recursive call immediately before a routine exits is tail recursive. Tail recursion is wasteful as it can be replaced by iteration thereby saving on the recursion stack. Good compilers automatically eliminate it. Non-tail recursive binary search
13
Avoiding Tail Recursion in QUICKSORT The second recursive call in QUICKSORT is tail recursive and can be eliminated int Fact(int n) { if (n < 1) return 1; else return n*Fact(n-1); } Tail recursion question: is the recursive Fact call tail recursive?
14
Problems Ex. 7.2-3 Ex. 7.2-4 Ex. 7.3-2 Ex. 7.4-5 The running time of quicksort can be improved in practice by taking advantage of the fast running time of insertion sort when its input is “nearly” sorted. When quicksort is called on a subarray with fewer than k elements, let it simply return without sorting the subarray. After the top- level call to quicksort returns, run insertion sort on the entire array to finish the sorting process. Argue that this sorting algorithm runs in O(nk +n lg(n/k)) expected time. How should k be picked, both in theory and in practice?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.