Data Structures and Algorithms I Day 9, 9/22/11 Heap Sort CMP 338 Data Structures and Algorithms I Day 9, 9/22/11 Heap Sort
Homework (due 11pm 9/27) Either, write a 4-sum program Running time should be ~ c N2 lg N public class Homework6 public static int sum4(double[] a) Or, Write a local maximum program forall 0<= i < N, 0 <= a[i] and a[0] = a[N-1] = 0 Find k such that a[k-1] <= a[k] & a[k+1] <= a[k] Running time should be ~c lg N public class Homework7 public static int lmax(double[] a)
Homework 9, due 11 pm 10/12 Implement insertion sort, merge sort, quicksort Compare performance of quicksort (four variations) insertion sort merge sort Turn in a) working code for all sort programs b) performance numbers (standard out) c) performance graphs d) your interpretation of the data
Quick Sort Worst-case: ~ N2/2 <'s; sort(Comparable[] a) StdRandom.shuffle(a); sort(a, 0, ||a||-1) sort(Comparable[] a, int lo, int hi) if (hi<=lo) return; int j = partition(a, lo, hi) sort(a, lo, j-1) sort(a, j+1, hi) Worst-case: ~ N2/2 <'s; Average-case: ~ 2N lg N <'s; ~ N lg N / 3 <=>'s Preferred, unless worst-case would be a disaster
Partitioning int partition(Comparable[] a, int lo, hi) int i=lo, j=hi+1 while (true); while (a[++i] < a[lo]) if (i==hi) break // necessary, why? while (a[lo] < a[--j]) if (j==lo) break // unnecessary, why? if (j<=i) exch(a, lo, j); return j exch(a, i, j)
Quicksort, what can go wrong? Partition doesn't split the region in half Pivot is too big Pivot is too small Too many elements are equal And partition doesn't stop for equal elements Fixes: Shuffle input once (average case) Choose a random pivot (average case) Use median as pivot (worst case) Linear median algorithm too expensive
Quick Select double select(Comparable[] a, int k) StdRandom.shuffle(a) int lo=0, hi = ||a||-1 while (hi>lo) int j = partition(a, lo, hi) if (j == k) return a[j] // return j in my version else if (k < j) hi = j-1 else if (j < k) lo = j+1
Linear Time Select double select(Comparable[] a, int k) StdRandom.shuffle(a) int lo=0, hi = ||a||-1 while (hi>lo) if 5 < hi-lo exch(a, lo, goodPivot(a, lo, hi)) int j = partition(a, lo, hi) if (j == k) return a[j] // return j in my version else if (k < j) hi = j-1 else if (j < k) lo = j+1
Good Pivot int goodPivot(double[] a, int lo, int hi) double[] b = new double[N/5] for (int j=0; j<N/5; j++) b[j] = b[median5(a, j*5)] int k = select(b, N/10, 0, (N/5)-1) return k*5 + 2 int median5(double[a], int lo) for (int i=lo; i<lo+3; i++) for (int j=i+1; j<lo+5; j++) if (a[j] < a[i]) exch(a, i, j) return lo+2
Heap Sort Worst-case: ~ 2N lg N <'s; ~ N lg N <=>'s sort(Comparable[] a) MaxPQ pq = new MaxPQ() for (int i=0; i<||a||; i++) pq.insert(a[i]) for (int i=||a||-1; 0<=i; i--) a[i] = pq.delMax() Worst-case: ~ 2N lg N <'s; ~ N lg N <=>'s Average-case: ~ 2N lg N <'s; ~ N lg N <=>'s Perfectly acceptable, no extra space required Quicksort and Merge sort may be slightly faster
Priority Queues Collections Stack – Last In, First Out Queue – First In, First Out MaxPQ – Biggest In, First Out MinPQ – Smallest In, First Out MaxPQ (MinPQ) operations public void insert(Key key) public Key delMax() public Key delMin()
Priority Queue Implementation Unordered array (selection sort) Insert ~ c <'s DelMax ~ c N <'s Ordered array (insertion sort) Insert ~ c N <'s DelMax ~ c <'s Heap (heap sort) Insert ~ lg N <'s DelMax ~ 2 lg N <'s
What is a Heap? Binary tree Invariant Each node is smaller (larger) than its children Operations insert Add a leaf swim – to reestablish invariant delMax Remove root, promote a leaf to root sink – to reestablish invariant
Sink or Swim swim compare with parent if out of order swap repeat sink Compare with largest (smallest) child
Sink and Swim in an Array Indices of children of node at index i: 2i and 2i+1 Root index is 1 (not 0) swim (int k) while i<k && a[k] < a[k/2] exch(k/2, k); k = k/2 sink(int k) while 2*k <= N j = 2*k if j<N && a[j] < a[j+1] j++ exch(j, k); k = j
Heap Sort in an Array Build heap Find min element and swap with index 0 int N = ||a||-1 for j=N; 0<j; j-- (~ cN) sink(j) Create sorted array while 0<N (~ cN lg N) exch(1, --N) sink(1)