Introduction to Algorithms Rabie A. Ramadan rabieramadan.org 4 Some of the sides are exported from different sources.

Slides:



Advertisements
Similar presentations
Algorithms Analysis Lecture 6 Quicksort. Quick Sort Divide and Conquer.
Advertisements

Divide-and-Conquer The most-well known algorithm design strategy:
Divide and Conquer Strategy
A. Levitin “Introduction to the Design & Analysis of Algorithms,” 3rd ed., Ch. 5 ©2012 Pearson Education, Inc. Upper Saddle River, NJ. All Rights Reserved.
Divide-and-Conquer Dr. Yingwu Zhu P65-74, p83-88, p93-96, p
1 Divide-and-Conquer The most-well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2. Solve smaller instances.
Divide and Conquer The most well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2. Solve smaller instances.
CS4413 Divide-and-Conquer
Chapter 4: Divide and Conquer Master Theorem, Mergesort, Quicksort, Binary Search, Binary Trees The Design and Analysis of Algorithms.
Theory of Algorithms: Divide and Conquer
Introduction to Algorithms Rabie A. Ramadan rabieramadan.org 6 Ack : Carola Wenk nad Dr. Thomas Ottmann tutorials.
Foundations of Algorithms, Fourth Edition
Analysis of Algorithms CS 477/677 Sorting – Part B Instructor: George Bebis (Chapter 7)
Chapter 4 Divide-and-Conquer Copyright © 2007 Pearson Addison-Wesley. All rights reserved.
Quicksort CS 3358 Data Structures. Sorting II/ Slide 2 Introduction Fastest known sorting algorithm in practice * Average case: O(N log N) * Worst case:
Analysis of Quicksort. Quicksort Algorithm Given an array of n elements (e.g., integers): If array only contains one element, return Else –pick one element.
Introduction to Algorithms Chapter 7: Quick Sort.
Sorting Algorithms and Average Case Time Complexity
Quicksort Divide-and-Conquer. Quicksort Algorithm Given an array S of n elements (e.g., integers): If array only contains one element, return it. Else.
Lecture 8 Jianjun Hu Department of Computer Science and Engineering University of South Carolina CSCE350 Algorithms and Data Structure.
Sorting Chapter 9.
CS 206 Introduction to Computer Science II 12 / 09 / 2009 Instructor: Michael Eckmann.
CS 253: Algorithms Chapter 7 Mergesort Quicksort Credit: Dr. George Bebis.
Sorting21 Recursive sorting algorithms Oh no, not again!
Chapter 4 Divide-and-Conquer Copyright © 2007 Pearson Addison-Wesley. All rights reserved.
Chapter 4: Divide and Conquer The Design and Analysis of Algorithms.
Design and Analysis of Algorithms - Chapter 41 Divide and Conquer The most well known algorithm design strategy: 1. Divide instance of problem into two.
Design and Analysis of Algorithms – Chapter 51 Divide and Conquer (I) Dr. Ying Lu RAIK 283: Data Structures & Algorithms.
Divide and Conquer The most well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2. Solve smaller instances.
Mergesort and Quicksort Chapter 8 Kruse and Ryba.
Design and Analysis of Algorithms - Chapter 41 Divide and Conquer The most well known algorithm design strategy: 1. Divide instance of problem into two.
Sorting (Part II: Divide and Conquer) CSE 373 Data Structures Lecture 14.
ALGORITHM ANALYSIS AND DESIGN INTRODUCTION TO ALGORITHMS CS 413 Divide and Conquer Algortihms: Binary search, merge sort.
Theory of Algorithms: Divide and Conquer James Gain and Edwin Blake {jgain | Department of Computer Science University of Cape Town.
Copyright © 2007 Pearson Addison-Wesley. All rights reserved. A. Levitin “ Introduction to the Design & Analysis of Algorithms, ” 2 nd ed., Ch. 1 Chapter.
A. Levitin “Introduction to the Design & Analysis of Algorithms,” 3rd ed., Ch. 5 ©2012 Pearson Education, Inc. Upper Saddle River, NJ. All Rights Reserved.
Sorting. Introduction Common problem: sort a list of values, starting from lowest to highest. List of exam scores Words of dictionary in alphabetical.
Sorting. Pseudocode of Insertion Sort Insertion Sort To sort array A[0..n-1], sort A[0..n-2] recursively and then insert A[n-1] in its proper place among.
Divide-and-Conquer The most-well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2.Solve smaller instances.
Divide And Conquer A large instance is solved as follows:  Divide the large instance into smaller instances.  Solve the smaller instances somehow. 
Lecture No. 04,05 Sorting.  A process that organizes a collection of data into either ascending or descending order.  Can be used as a first step for.
Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer.
Divide and Conquer Strategy
Young CS 331 D&A of Algo. Topic: Divide and Conquer1 Divide-and-Conquer General idea: Divide a problem into subprograms of the same kind; solve subprograms.
Sorting divide and conquer. Divide-and-conquer  a recursive design technique  solve small problem directly  divide large problem into two subproblems,
Review 1 Insertion Sort Insertion Sort Algorithm Time Complexity Best case Average case Worst case Examples.
Nothing is particularly hard if you divide it into small jobs. Henry Ford Nothing is particularly hard if you divide it into small jobs. Henry Ford.
Concepts of Algorithms CSC-244 Unit 17 & 18 Divide-and-conquer Algorithms Quick Sort Shahid Iqbal Lone Computer College Qassim University K.S.A.
Lecture 6 Sorting II Divide-and-Conquer Algorithms.
Computer Sciences Department1. Sorting algorithm 4 Computer Sciences Department3.
CMPT 238 Data Structures More on Sorting: Merge Sort and Quicksort.
Subject Name: Design and Analysis of Algorithm Subject Code: 10CS43
Chapter 4 Divide-and-Conquer
Sorting Chapter 13 presents several common algorithms for sorting an array of integers. Two slow but simple algorithms are Selectionsort and Insertionsort.
Divide-and-Conquer The most-well known algorithm design strategy:
Chapter 4 Divide-and-Conquer
Algorithm Design Methods
Divide-and-Conquer The most-well known algorithm design strategy:
Chapter 4: Divide and Conquer
Quicksort Algorithm Given an array of n elements (e.g., integers):
Divide-and-Conquer The most-well known algorithm design strategy:
Chapter 4 Divide-and-Conquer
Chapter 4.
Divide-and-Conquer The most-well known algorithm design strategy:
Algorithms Dr. Youn-Hee Han April-May 2013
CSC 380: Design and Analysis of Algorithms
CSC 380: Design and Analysis of Algorithms
CSC 380: Design and Analysis of Algorithms
Divide and Conquer Merge sort and quick sort Binary search
Presentation transcript:

Introduction to Algorithms Rabie A. Ramadan rabieramadan.org 4 Some of the sides are exported from different sources to clarify the topic

Chapter 4 Divide-and-Conquer Copyright © 2007 Pearson Addison-Wesley. All rights reserved. Acknowledgment : Some of the slides are based on a tutorial made by Kruse and Ryba

Divide-and-Conquer The most-well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2. Solve smaller instances recursively 3. Obtain solution to original (larger) instance by combining these solutions

Divide-and-Conquer Technique (cont.) subproblem 2 of size n/2 subproblem 1 of size n/2 a solution to subproblem 1 a solution to the original problem a solution to subproblem 2 a problem of size n (instance) It general leads to a recursive algorithm!

Divide-and-Conquer Examples Sorting: mergesort and quicksort Binary tree traversals Binary search Multiplication of large integers Matrix multiplication: Strassen’s algorithm Closest-pair and convex-hull algorithms

General Divide-and-Conquer Recurrence General case analysis n Given a problem of size n (n/b) Assume that can be divided into b instances of size (n/b) a a problems of (n/b) are the one that solved f(n) The time needed for the dividing the problem and summing the solutions back is f(n) Time complexity of Divide and Conquer T(n) = aT(n/b) + f (n)

General Divide-and-Conquer Recurrence The complexity of divide and conquer depends on values of a and b T(n) = aT(n/b) + f (n) where f(n)   (n d ), d  0 Master Theorem: If a < b d, T(n)   (n d ) (Case 1) If a = b d, T(n)   (n d log n) (Case 2) If a = b d, T(n)   (n d log n) (Case 2) If a > b d, T(n)   (n log b a ) (Case 3) If a > b d, T(n)   (n log b a ) (Case 3) Note: The same results hold with O instead of .

Group Activity 8 Compute the Complexity of the following functions in terms of T(n) = 4T(n/2) + n  T(n)  ? T(n) = 4T(n/2) + n 2  T(n)  ? T(n) = 4T(n/2) + n 2  T(n)  ? T(n) = 4T(n/2) + n 3  T(n)  ? T(n) = 4T(n/2) + n 3  T(n)  ? T(n) = 2T(n/2) + 1  T(n)  ? T(n) = 2T(n/2) + 1  T(n)  ?  (n^2) Case 3  (n^2log n) Case 2  (n^3) Case 1   (n) Case 3

Mergesort Split array A[0..n-1] into about equal halves and make copies of each half in arrays B and C Sort arrays B and C recursively Merge sorted arrays B and C into array A as follows: Repeat the following until no elements remain in one of the arrays: compare the first elements in the remaining unprocessed portions of the arrays copy the smaller of the two into A, while incrementing the index indicating the unprocessed portion of that array Once all elements in one of the arrays are processed, copy the remaining unprocessed elements from the other array into A.

Pseudocode of Mergesort

Mergesort Example

Group Activity Write the Pseudocode of Merge part? Θ(p+q)Θ(n) Time complexity: Θ(p+q) = Θ(n) comparisons

Analysis of Mergesort At every step, I divide the elements by 2 b Then b =2 2 Also the number of problems to be solved with each subproblem every time is a= 2 f(n) ???? f(n) ???? F(n)(n-1) F(n) requires in the worst case almost (n-1) comparisons based * the number of recurrences. T(n) = 2T(n/2) + n-1 =??? T(n) = 2T(n/2) + n-1 =??? Space requirement: Θ(n) (not in-place) Space requirement: Θ(n) (not in-place) T(n) = 2T(n/2) + f(n), T(1) = 0 If a = b d, T(n)   (n d log n) =  (n log n)  (n log n)

Quicksort Select a pivot (partitioning element) – here, the first element Rearrange the list so that all the elements in the first s positions are smaller than or equal to the pivot and all the elements in the remaining n-s positions are larger than or equal to the pivot Exchange the pivot with the last element in the first (i.e.,  ) subarray — the pivot is now in its final position Sort the two subarrays recursively v S v S1S2

Dividing Process (s, i, j) For each partition, you select the pivot index, and first and last elements indexes (s, i, j) i i moves from left-to-right (looks for elements smaller than the pivot) j j moves from right-to-left (looks for elements greater than the pivot) When both stops, we got three cases : i< j  Swap (A[i], A[j]) i> j  array is partitioned Swap( pivot A[s], A[j]) i=j  A[i]=A[j]=A[s]

Example We are given array of n integers to sort:

Pick Pivot Element There are a number of ways to pick the pivot element. In this example, we will use the first element in the array:

Partitioning Array Given a pivot, partition the elements of the array such that the resulting array consists of: 1. One sub-array that contains elements >= pivot 2. Another sub-array that contains elements < pivot The sub-arrays are stored in the original data array. Partitioning loops through, swapping elements below/above pivot.

pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

pivot_index = 0 too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 4 too_big_index too_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

Partition Result <= data[pivot]> data[pivot] [0] [1] [2] [3] [4] [5] [6] [7] [8]

Recursion: Quicksort Sub-arrays <= data[pivot]> data[pivot] [0] [1] [2] [3] [4] [5] [6] [7] [8]

Group Activity Write a pseudocode for the Quicksort ?

Partitioning Algorithm Θ(r-l) Time complexity: Θ(r-l) comparisons or i > r or j = l <

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Try it with your classmates ?

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Recursion: 1. Partition splits array in two sub-arrays of size n/2 2. Quicksort each sub-array

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Recursion: 1. Partition splits array in two sub-arrays of size n/2 2. Quicksort each sub-array Depth of recursion tree?

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Recursion: 1. Partition splits array in two sub-arrays of size n/2 2. Quicksort each sub-array Depth of recursion tree? O(log 2 n)

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Recursion: 1. Partition splits array in two sub-arrays of size n/2 2. Quicksort each sub-array Depth of recursion tree? O(log 2 n) Number of accesses in partition?

Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? Recursion: 1. Partition splits array in two sub-arrays of size n/2 2. Quicksort each sub-array Depth of recursion tree? O(log 2 n) Number of accesses in partition? O(n)

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n)

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time?

Quicksort: Worst Case Assume first element is chosen as pivot. Assume we get array that is already in order: pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 too_big_indextoo_small_index [0] [1] [2] [3] [4] [5] [6] [7] [8]

1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] pivot_index = 0 > data[pivot]<= data[pivot] [0] [1] [2] [3] [4] [5] [6] [7] [8]

Quick Sort 1-64

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? Recursion: 1. Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2. Quicksort each sub-array Depth of recursion tree?

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? Recursion: 1. Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2. Quicksort each sub-array Depth of recursion tree? O(n)

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? Recursion: 1. Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2. Quicksort each sub-array Depth of recursion tree? O(n) Number of accesses per partition?

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? Recursion: 1. Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2. Quicksort each sub-array Depth of recursion tree? O(n) Number of accesses per partition? O(n)

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time: O(n 2 )!!!

Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time: O(n 2 )!!! What can we do to avoid worst case?

Analysis of Quicksort Best case: split in the middle — Θ(n log n) Worst case: sorted array! — Θ(n 2 ) Average case: random arrays — Θ(n log n) Improvements Improvements: better pivot selection: median of three partitioning switch to insertion sort on small subfiles elimination of recursion These combine to 20-25% improvement T(n) = T(n-1) + Θ(n)