Sei sulla pagina 1di 28

Algoritmen & Datastructuren

2014 2015
Quicksort
Philip Dutr
Dept. of Computer Science, K.U.Leuven

Overview Lecture
Quicksort
Quicksort partitioning

Variant 1
Variant 2
Variant 3

Running Times
Performance Analysis

Worst
Best
Average

Optimizations
Summary

Copyright Ph.Dutr, Spring 2015

Sorting algorithms so far

Insertion sort: ~n2/4 comparisons average case

Selection sort: ~n2/2 comparisons

In-place sorting

In-place sorting

Merge sort: ~n.log2n comparisons

Not in-place (additional memory needed)

http://www.youtube.com/watch?v=k4RRi_ntQc8&feature=related
3

Copyright Ph.Dutr, Spring 2015

How fast can sorting algorithms go?


Comparison sorts

Sort by comparing two elements


Any comparison sort needs at least ~n. log2n comparisons

Merge sort is asymptotically optimal!

Non-comparison sorts, in linear (~ n) time:

Counting sort
Radix sort
Bucket sort
See next lecture!

Copyright Ph.Dutr, Spring 2015

Quicksort (section 2.3)


Most widely used sorting algorithm (e.g. Java)
In-place

No additional memory needed

~1.39.n.log2n on average

Mergesort:

Recurse first (trivial), then merge (do real work)

Quicksort:

Partition first (do real work), then recurse (trivial)


Copyright Ph.Dutr, Spring 2015

Quicksort
Partitioning of elements:

Choose pivot element, e.g. a[j]


Elements a[lo] a[j-1] a[j]
Elements a[j+1] a[hi] a[j]

Copyright Ph.Dutr, Spring 2015

Quicksort
public class Quick
{ // Quicksort.
public static void sort(Comparable[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
}
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi); // Partition
sort(a, lo, j-1); // Sort left part a[lo .. j-1].
sort(a, j+1, hi); // Sort right part a[j+1 .. hi].
}
}

Copyright Ph.Dutr, Spring 2015

Quicksort

Copyright Ph.Dutr, Spring 2015

Quicksort

Charles Hoare (1934)

Quicksort: 1960

ACM Turing Award 1980

1972 Edsger W. Dijkstra


1974 Donald E. Knuth
1988 Ivan Sutherland
2003 Alan Kay

Copyright Ph.Dutr, Spring 2015

Quicksort

http://www.youtube.com/watch?v=2HjspVV0jK4

10

Copyright Ph.Dutr, Spring 2015

Quicksort: partitioning, variant 1

Choose pivot element (e.g. first element)


Create 2 arrays: left[] and right[]
Loop over all elements

If element < pivot, put into left[]


If element > pivot, put into right[]
(if element == pivot, left or right)

Concatenate left[] + pivot + right []


n-1 number of comparisons
11

Copyright Ph.Dutr, Spring 2015

Quicksort: partitioning, variant 2


private static int partition(Comparable[] a, int lo, int hi)
{ // Partition into a[lo..i-1], a[i], a[i+1..hi].
int i = lo, j = hi+1; // left and right scan indices
Comparable v = a[lo]; // partitioning value
while (true)
{ // Scan right - left, check for scan complete, and exchange
while (less(a[++i], v)) if (i == hi) break;
while (less(v, a[--j])) if (j == lo) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j); // Put v = a[j] into position
return j; // with a[lo..j-1] <= a[j] <= a[j+1..hi].
}

n+1 number of comparisons


12

Copyright Ph.Dutr, Spring 2015

Quicksort: partitioning, variant 2

13

Copyright Ph.Dutr, Spring 2015

Quicksort: partitioning, variant 3 (Lomuto)

14

Copyright Ph.Dutr, Spring 2015

15

Copyright Ph.Dutr, Spring 2015

16

Copyright Ph.Dutr, Spring 2015

Quicksort: partitioning, variant 3 (Lomuto)


private static int partition(Comparable[] a, int lo, int hi)
{ // Partition into a[lo..i], a[i+1], a[i+1..hi].
int i = lo-1; // scan index
Comparable v = a[hi]; // partitioning value
for (int j = lo; j <= hi-1; j++)
{ // scan all elements
if (less(a[j],v)) {
i++;
exch(a, i, j);
}
}
exch(a, i+1, hi); // Put v into position
return i+1; // with a[lo..i] <= a[i+1] <= a[i+1..hi].
}

n-1 number of comparisons


17

Copyright Ph.Dutr, Spring 2015

Running times

Home PC executes 108 compares/second.


Supercomputer executes 1012 compares/second

Lesson 1: Good algorithms are a better investment than


supercomputers.
Lesson 2: Great algorithms are better than good ones.
18

Copyright Ph.Dutr, Spring 2015

Performance of quicksort

Worst case

0 elements in one subarray and


n 1 elements in the other
T(n) = T(n 1) +T (0) + partitioning(n)
= T(n 1) + (n-1)
= ~ n2/2

worst-case running time occurs if array is already sorted

insertion sort runs in ~n time in this case

19

Copyright Ph.Dutr, Spring 2015

Worst case

20

Copyright Ph.Dutr, Spring 2015

Performance of quicksort

Best Case

Suppose split is at 9/10

Split is balanced
T(n) = 2T(n/2) + partitioning(n)
= ~n . log2 n

T(n) = T(9n/10) +T(n/10)+ partitioning(n)


= ~c . n . log2 n

Suppose split is at 99/100, 999/1000,

21

T(n) = ~c . n . log2 n
Copyright Ph.Dutr, Spring 2015

Best case

22

Copyright Ph.Dutr, Spring 2015

23

Copyright Ph.Dutr, Spring 2015

Performance of quicksort:
Intuition for the average case

Any permutation of elements can form the initial array


Some splits will be good, others will be bad

24

Copyright Ph.Dutr, Spring 2015

Performance: average case

(mathematical derivation on blackboard)

25

Copyright Ph.Dutr, Spring 2015

Optimizations

Cuttoff to insertion sort

Median of 3 values for pivot

Practice: ~ 10 elements
Better probability of splitting in half

Many similar values

26

3-way partitioning (less, equal, greater)

Copyright Ph.Dutr, Spring 2015

Optimizations

27

Copyright Ph.Dutr, Spring 2015

Summary of performance

Worst case

Average case

Number of compares is ~ 1.39 n log2 n


39% more compares than mergesort
But faster than mergesort in practice because of less data
movement.

Random shuffle

Number of compares is quadratic


But youll win the lottery first!

Probabilistic guarantee against worst case


Basis for math model that can be validated with experiments.

Many textbook implementations go quadratic if array

28

Is sorted or reverse sorted


Has many duplicates (even if randomized!)
Copyright Ph.Dutr, Spring 2015

Potrebbero piacerti anche