Data Structures and Algorithms CS 244

Slides:



Advertisements
Similar presentations
Chapter 9 continued: Quicksort
Advertisements

Quick Sort, Shell Sort, Counting Sort, Radix Sort AND Bucket Sort
CSCE 3110 Data Structures & Algorithm Analysis
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.
25 May Quick Sort (11.2) CSE 2011 Winter 2011.
Introduction to Algorithms Rabie A. Ramadan rabieramadan.org 4 Some of the sides are exported from different sources.
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.
© 2004 Goodrich, Tamassia Quick-Sort     29  9.
Sorting Chapter 9.
Fundamentals of Algorithms MCS - 2 Lecture # 16. Quick Sort.
CS 206 Introduction to Computer Science II 12 / 09 / 2009 Instructor: Michael Eckmann.
Chapter 11 Sorting and Searching. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Examine the linear search and.
Mergesort and Quicksort Chapter 8 Kruse and Ryba.
CS 206 Introduction to Computer Science II 12 / 08 / 2008 Instructor: Michael Eckmann.
Merge Sort. What Is Sorting? To arrange a collection of items in some specified order. Numerical order Lexicographical order Input: sequence of numbers.
General Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Order Statistics David Kauchak cs302 Spring 2012.
Review and Prepare for Test 3 CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science.
Bubble Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and.
HelloWorld – GameOver CS 244 – Data Structures and Algorithms Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout.
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.
Merge Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer.
Priority Queues and Heaps Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University.
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.
Computer Sciences Department1. Sorting algorithm 4 Computer Sciences Department3.
Algorithm Design Techniques, Greedy Method – Knapsack Problem, Job Sequencing, Divide and Conquer Method – Quick Sort, Finding Maximum and Minimum, Dynamic.
Advanced Sorting.
School of Computing Clemson University Fall, 2012
Chapter 11 Sorting Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and Mount.
Sorting.
CSCI 104 Sorting Algorithms
Sorting Chapter 13 presents several common algorithms for sorting an array of integers. Two slow but simple algorithms are Selectionsort and Insertionsort.
Quick-Sort 9/13/2018 1:15 AM Quick-Sort     2
Chapter 7 Sorting Spring 14
Quicksort "There's nothing in your head the sorting hat can't see. So try me on and I will tell you where you ought to be." -The Sorting Hat, Harry Potter.
Week 12 - Wednesday CS221.
CSE 143 Lecture 23: quick sort.
More on Merge Sort CS 244 This presentation is not given in class
CSC 413/513: Intro to Algorithms
Quicksort 1.
Algorithm Design Methods
Algorithm Design and Analysis (ADA)
CS 3343: Analysis of Algorithms
Binary Search Back in the days when phone numbers weren’t stored in cell phones, you might have actually had to look them up in a phonebook. How did you.
Quick Sort (11.2) CSE 2011 Winter November 2018.
Quicksort Algorithm Given an array of n elements (e.g., integers):
Quicksort analysis Bubble sort
Unit-2 Divide and Conquer
Sorting Algorithms Ellysa N. Kosinaya.
Sub-Quadratic Sorting Algorithms
Review and Prepare for Test 2
Sorting Chapter 13 presents several common algorithms for sorting an array of integers. Two slow but simple algorithms are Selectionsort and Insertionsort.
Chapter 4.
Linear-Time Sorting Algorithms
EE 312 Software Design and Implementation I

Quicksort.
Copyright © Aiman Hanna All rights reserved
Sorting.
Data Structures & Algorithms
Quicksort.
Quicksort and Randomized Algs
Design and Analysis of Algorithms
Algorithm Efficiency and Sorting
Quicksort.
Chapter 11 Sets, and Selection
Presentation transcript:

Data Structures and Algorithms CS 244 Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout Based on the book: Data Structures and Algorithms in C++ (Goodrich, Tamassia, Mount) Some content from Data Structures Using C++ (D.S. Malik)

News! Second Test moved to April 17 unless there are any objections? This is to allow you the chance to complete the quiz PRIOR to the test day Quiz will still be due April 15 – BEFORE class Expect it to become available soon so you can take it across the weekend

Previously Sorts Searches Insertion Sort Selection Sort Bubble Sort Merge Sort Searches Linear (sequential) Search Binary Search

QuickSort Algorithm Given an array of n elements (e.g., integers): If array only contains one element, return Else pick one element to use as pivot. Partition elements into two sub-arrays: Elements less than or equal to pivot Elements greater than pivot Quicksort two sub-arrays Return results recursive calls

Example We are given array of n integers to sort: 40 20 10 80 60 50 7 30 100

Pick Pivot Element 40 20 10 80 60 50 7 30 100 There are a number of ways to pick the pivot element. In this example, we will use the first element in the array: We will see other (better) choices later

Partition into 2 “sub-sets” 40 20 10 80 60 50 7 30 100 Goal is to partition the array into 2 sub-arrays such that One sub-array contains elements >= pivot The other sub-array contains elements < pivot Partitioning will loop through the array swapping elements less than and greater than the pivot.

Partition into 2 “sub-sets” BiggerIndex = 1 SmallerIndex = 8 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 1 SmallerIndex = 8 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 20 <= 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 2 SmallerIndex = 8 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 10 <= 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 8 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 80 <= 40 ? --- no While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 8 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 100 > 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 30 > 40 ? --- no While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 80 60 50 7 30 100 pivotIndex = 0 Swap While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 Swap While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 3 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 30 <= 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 60 <= 40 ? --- no While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 7 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 80 > 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 7 > 40 ? --- no While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 60 50 7 80 100 pivotIndex = 0 Swap While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 Swap While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 4 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 7 <= 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 50 <= 40 ? --- no While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 SmallerIndex = 6 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 60 > 40 ? --- yes While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 SmallerIndex = 5 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” BiggerIndex = 5 Swap [0] [1] [2] [3] [4] [5] [6] [7] [8] 40 20 10 30 7 50 60 80 100 pivotIndex = 0 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” Swap [0] [1] [2] [3] [4] [5] [6] [7] [8] 7 20 10 30 40 50 60 80 100 pivotIndex = 0 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Partition into 2 “sub-sets” [0] [1] [2] [3] [4] [5] [6] [7] [8] 7 20 10 30 40 50 60 80 100 pivotIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex] There perhaps should be a step 6 that says update pivotIndex…

Partition Result [0] [1] [2] [3] [4] [5] [6] [7] [8] <= data[pivot] [0] [1] [2] [3] [4] [5] [6] [7] [8] 7 20 10 30 40 50 60 80 100 <= data[pivot] > data[pivot] 40 20 10 80 60 50 7 30 100  original order of stuff Notice order of numbers can change in some quick sort implementations (as shown) ( these are not “stable” – which is ok) Some implementations keep things in same order these are not the most efficient implementations of quick sort (i.e. run slow) Such an implementation would result in the partition: 20, 10, 7, 30 ] 40 [ 80, 60, 50, 100

Recursively QuickSort the SubArrays [0] [1] [2] [3] [4] [5] [6] [7] [8] 7 20 10 30 40 50 60 80 100 <= data[pivot] > data[pivot]

QuickSort Analysis Assuming the keys are random, uniformly distributed Then the two sub-arrays will be nearly the same size for each recursive call. Recall MergeSort worked in a similar fashion Dividing the data into 2 subsets of similar size So the runtime would once again depend on the number of times the original data size, n, can be divided by two i.e. lg n

QuickSort Analysis In very similar fashion as to the analysis of MergeSort, with the assumption the keys are random uniformly distributed, The runtime of QuickSort is usually taken to be O(n lg n) However…

QuickSort – Worst Case Using QuickSort requires some wisdom about your data And selecting a good pivot point =) Let’s consider a bad scenario for QuickSort

Bad Scenario for QuickSort Assume the first element is always the pivot Assume the given data to sort is already in order (or very nearly, but let’s be extreme) 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 8

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 8 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 8 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 7 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 6 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 5 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 4 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 3 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 2 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 1 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 0 While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } While data[SmallerIndex] > data[pivot] { --SmallerIndex; } If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } While SmallerIndex > BiggerIndex, go to 1. Swap data[SmallerIndex] and data[pivotIndex]

Bad Scenario for QuickSort 2 4 10 12 13 50 57 63 100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] <= data[pivot] > data[pivot] The recursive calls do not divide anything in half… So there will be n recursive calls, each doing n-1 operations Which leads to O(n2) performance Not quick

Median of 3 – Avoid the Bad To avoid such bad scenarios a better choice of pivot is typically used: Use the median of 3 rule: Pick the median value of 3 elements from the data array as the pivot Specifically: data[0], data[n/2] and data[n-1] Example: data[0] = 10, data[n/2] = 50, data[n-1] = 70 median = 50 so use index = n/2 for the pivot (value of 50)

QuickSort Note – Small Arrays For very small arrays (circa n <= 20) quicksort in physical time does not perform as well as insertion sort And – because quicksort is recursive – these cases occur frequently. Common solution When the array size becomes “sufficiently” small do not use quicksort recursively instead use a sorting algorithm that is more efficient for small arrays (such as insertion sort) Do NOT apply this on homework or exams

Questions Any questions about Quick Sort?

Summary of Sorting Algorithms (so far) Time Notes Selection Sort O(n2) Slow, in-place For small data sets Insertion Sort Bubble Sort Heap Sort O(nlog n) Fast, in-place For large data sets Merge Sort O(nlogn) Fast, sequential data access For huge data sets Quick Sort Assumes key values are random and uniformly distributed Place holder for others we have not yet seen

The End of This Part End