Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer.

Slides:



Advertisements
Similar presentations
Chapter 9 continued: Quicksort
Advertisements

Introduction to Algorithms Quicksort
David Luebke 1 4/22/2015 CS 332: Algorithms Quicksort.
Algorithms Analysis Lecture 6 Quicksort. Quick Sort Divide and Conquer.
Sorting Comparison-based algorithm review –You should know most of the algorithms –We will concentrate on their analyses –Special emphasis: Heapsort Lower.
Quick Sort, Shell Sort, Counting Sort, Radix Sort AND Bucket Sort
CSCE 3110 Data Structures & Algorithm Analysis
Using Divide and Conquer for Sorting
Insertion Sort. Selection Sort. Bubble Sort. Heap Sort. Merge-sort. Quick-sort. 2 CPSC 3200 University of Tennessee at Chattanooga – Summer 2013 © 2010.
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.
CS 206 Introduction to Computer Science II 04 / 28 / 2009 Instructor: Michael Eckmann.
25 May Quick Sort (11.2) CSE 2011 Winter 2011.
Copyright (C) Gal Kaminka Data Structures and Algorithms Sorting II: Divide and Conquer Sorting Gal A. Kaminka Computer Science Department.
© 2004 Goodrich, Tamassia Quick-Sort     29  9.
Sorting Algorithms and Average Case Time Complexity
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.
Ver. 1.0 Session 5 Data Structures and Algorithms Objectives In this session, you will learn to: Sort data by using quick sort Sort data by using merge.
CS 206 Introduction to Computer Science II 04 / 27 / 2009 Instructor: Michael Eckmann.
CS 206 Introduction to Computer Science II 12 / 09 / 2009 Instructor: Michael Eckmann.
Sorting Heapsort Quick review of basic sorting methods Lower bounds for comparison-based methods Non-comparison based sorting.
© 2006 Pearson Addison-Wesley. All rights reserved10-1 Chapter 10 Algorithm Efficiency and Sorting CS102 Sections 51 and 52 Marc Smith and Jim Ten Eyck.
Chapter 11 Sorting and Searching. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Examine the linear search and.
CS 206 Introduction to Computer Science II 12 / 05 / 2008 Instructor: Michael Eckmann.
Chapter 4: Divide and Conquer The Design and Analysis of Algorithms.
CHAPTER 11 Sorting.
Quicksort.
CS 206 Introduction to Computer Science II 12 / 03 / 2008 Instructor: Michael Eckmann.
Quicksort.
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.
CS 206 Introduction to Computer Science II 12 / 08 / 2008 Instructor: Michael Eckmann.
Design and Analysis of Algorithms - Chapter 41 Divide and Conquer The most well known algorithm design strategy: 1. Divide instance of problem into two.
Merge Sort. What Is Sorting? To arrange a collection of items in some specified order. Numerical order Lexicographical order Input: sequence of numbers.
Order Statistics. Order statistics Given an input of n values and an integer i, we wish to find the i’th largest value. There are i-1 elements smaller.
The Selection Problem. 2 Median and Order Statistics In this section, we will study algorithms for finding the i th smallest element in a set of n elements.
CS 61B Data Structures and Programming Methodology July 28, 2008 David Sun.
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.
Chapter 5 Searching and Sorting. Copyright © 2004 Pearson Addison-Wesley. All rights reserved.1-2 Chapter Objectives Examine the linear search and binary.
Bubble Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and.
Searching CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Priority Queues and Sorting CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science.
Chapter 8 Sorting and Searching Goals: 1.Java implementation of sorting algorithms 2.Selection and Insertion Sorts 3.Recursive Sorts: Mergesort and Quicksort.
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.
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.
Merge Sort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
Sorting and Searching by Dr P.Padmanabham Professor (CSE)&Director
Priority Queues and Heaps Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University.
Sorting divide and conquer. Divide-and-conquer  a recursive design technique  solve small problem directly  divide large problem into two subproblems,
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.
Sorting – Lecture 3 More about Merge Sort, Quick Sort.
Trees Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
CMPT 238 Data Structures More on Sorting: Merge Sort and Quicksort.
INTRO2CS Tirgul 8 1. Searching and Sorting  Tips for debugging  Binary search  Sorting algorithms:  Bogo sort  Bubble sort  Quick sort and maybe.
Chapter 11 Sorting Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and Mount.
Sorting.
CSE 143 Lecture 23: quick sort.
More on Merge Sort CS 244 This presentation is not given in class
Quicksort Algorithm Given an array of n elements (e.g., integers):
Review and Prepare for Test 2
Data Structures and Algorithms CS 244
Presentation transcript:

Quicksort Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout Content derived from: Data Structures Using C++ (D.S. Malik) and Data Structures and Algorithms in C++ (Goodrich, Tamassia, Mount)c

Previously Sorts Insertion Sort Selection Sort Bubble 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:

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: We will see other (better) choices later

Partition into 2 “sub-sets” Goal is to partition the array into 2 sub-arrays such that 1.One sub-array contains elements >= pivot 2.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” 1.While data[BiggerIndex] <= data[pivot] { ++BiggerIndex; } 2.While data[SmallerIndex] > data[pivot] { --SmallerIndex; } 3.If BiggerIndex < SmallerIndex { swap BiggerIndex] and SmallerIndex] } 4.While SmallerIndex > BiggerIndex, go to 1. 5.Swap data[SmallerIndex] and data[pivotIndex] [0] [1] [2] [3] [4] [5] [6] [7] [8] pivotIndex = 0 BiggerIndex = 1 SmallerIndex = 8

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Recursively QuickSort the SubArrays [0] [1] [2] [3] [4] [5] [6] [7] [8] <= 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) pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] BiggerIndex = 1 SmallerIndex = 8

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

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

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

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

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

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

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

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

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

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

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

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

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

Bad Scenario for QuickSort 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(n 2 ) 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) AlgorithmTimeNotes Selection SortO(n 2 )Slow, in-place For small data sets Insertion SortO(n 2 )Slow, in-place For small data sets Bubble SortO(n 2 )Slow, in-place For small data sets Heap SortO(nlog n)Fast, in-place For large data sets Merge SortO(nlogn)Fast, sequential data access For huge data sets Quick SortO(nlogn)Assumes key values are random and uniformly distributed Place holder for others we have not yet seen

The End of This Part End