Presentation is loading. Please wait.

Presentation is loading. Please wait.

Data Structures and Algorithms (AT70. 02) Comp. Sc. and Inf. Mgmt

Similar presentations


Presentation on theme: "Data Structures and Algorithms (AT70. 02) Comp. Sc. and Inf. Mgmt"— Presentation transcript:

1 Data Structures and Algorithms (AT70. 02) Comp. Sc. and Inf. Mgmt
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

3

4 pivot From i +1 to j is a window of elements > x = A[r]. The cursor j moves right one step at a time. If the cursor j “discovers” an element ≤ x, then this element is swapped with the front element of the window, effectively moving the window right one step; if it discovers an element > x, then the window simply becomes longer one unit.

5 Do Ex

6 Performance of Quicksort
Worst-case partitioning: one subproblem of size n-1, other 0. Time: (n2). 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).

7

8

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 z1, z2, …, zn, where z1≤ z2 ≤ … ≤ zn
Let the indicator random variable Xij = I{zi is compared to zj}. Then X = ∑i=1..n-1 ∑j=i+1..n Xij Therefore, E[X] = E[ ∑i=1..n-1 ∑j=i+1..n Xij ] = ∑i=1..n-1 ∑j=i+1..n Pr{zi is compared to zj} Now, zi and zj are compared iff the first element to be chosen from Zij = [zi, zi+1, …, zj] as pivot is either zi or zj. Prior to the point when an element of Zij is chosen as pivot, all of Zij is in the same partition. Because pivots are chosen randomly any element of Zij is equally likely to be the first chosen as pivot. We conclude: Pr{zi is compared to zj} = 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 ∑k=1..n 1/k ≈ loge n

11 Hoare’s Original Partitioning Strategy
Do Prob. 7-1a

12 Tail Recursion Tail recursive binary search
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; else return (Mid); // X has been located 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 } 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. Optimized 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 Tail recursion question: is the recursive Fact call tail recursive? int Fact(int n) { if (n < 1) return 1; else return n*Fact(n-1); }

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?


Download ppt "Data Structures and Algorithms (AT70. 02) Comp. Sc. and Inf. Mgmt"

Similar presentations


Ads by Google