Algorithms III
Total Page:16
File Type:pdf, Size:1020Kb
Algorithms III 1 Agenda Sorting • Simple sorting algorithms • Shellsort • Mergesort • Quicksort • A lower bound for sorting • Counting sort and Radix sort Randomization • Random number generation • Generation of random permutations • Randomized algorithms 2 Sorting Informal definition: Sorting is any process of arranging items in some sequence. Why sort? (1) Searching a sorted array is easier than searching an unsorted array. This is especially true for people. Example: Looking up a person in a telephone book. (2) Many problems may be solved more efficiently when input is sorted. Example: If two files are sorted it is possible to find all duplicates in only one pass. 3 Detecting duplicates in an array If the array is sorted, duplicates can be detected by a linear-time scan of the array: for (int i = 1; i < a.length; i++) if (a[i - 1].equals(a[i]) return true; 4 Finding the intersection of two! unsorted arrays 0 i M a: 0 j N b: 0 k c: k = 0; for (i = 0; i < M; i++) for (j = 0; j < N; j++) if (a[i].equals(b[j])) c[k++] = a[i]; Complexity: O(MN) 5 Finding the intersection of two! sorted arrays 0 i M a: 0 j N b: 0 k c: i = j = k = 0; while (i < M && j < N) if (a[i] < b[j]) i++; else if (a[i] > b[j]) j++; else { c[k++] = a[i]; i++; j++; } Complexity: O(M + N) 6 Insertion sort Problem: Given an array a of n elements a[0], a[1], ..., a[n-1]. Sort the array in increasing order. Solution (by induction): Base case: We know how to sort 1 element. Induction hypothesis: We know how to sort n-1 elements. We can sort an array of n elements by (1) sorting its first n-1 elements, (2) insert the n’th element into its proper place among the previously sorted elements 7 Insertion sort (recursive version) void insertionSort(int[] a, int n) { if (n > 1) { insertionSort(a, n - 1); int tmp = a[n]; int j = n; for ( ; j > 0 && a[j - 1] > tmp; j--) a[j] = a[j - 1]; a[j] = tmp; } } Single right shift 8 9 10 A S O R T I N G E X A M P L E A S O R T I N G E X A M P L E A O S R T I N G E X A M P L E A O R S T I N G E X A M P L E A O R S T I N G E X A M P L E A I O R S T N G E X A M P L E A I N O R S T G E X A M P L E A G I N O R S T E X A M P L E A E G I N O R S T X A M P L E A E G I N O R S T X A M P L E A A E G I N O R S T X M P L E A A E G I M N O R S T X P L E A A E G I M N O P R S T X L E A A E G I L M N O P R S T X E A A E E G I L M N O P R S T X 11 Insertion sort (non-recursive version) Only the object references are right-shifted (not the objects themselves) 12 Animation of Insertion sort a[i] i Sorting the integers from 1 to 100. 13 Analysis of Insertion sort Number of comparisons: Best case: n-1 Worst case: 1 + 2 + ... + (n-1) = n(n-1)/2, which is O(n2) Average case: n(n-1)/4, which is O(n2) Number of moves: Best case: 0 Worst case: 1 + 2 + ... + (n-1) = n(n-1)/2, which is O(n2) Average case: n(n-1)/4, which is O(n2) Running time is O(n) for “almost sorted” arrays 14 Shellsort! Donald Shell, 1959 Idea: Insertion sort is very efficient when the array is “almost sorted”. However, it is slow for “very unsorted” arrays since it only allows exchange of neighboring elements. Question: Can we start by exchanging elements that are far apart from each other in the array before we do an ordinary Insertion sort? Answer: Yes. We can start by sorting all subfiles consisting of every h’th element of the array, where h > 1. 15 4-sorting 1. Divide the array into 4 subfiles: each 4’th element, starting in the first, each 4’th element, starting in the second, each 4’th element, starting in the third, and each 4’th element, starting in the fourth. 2. Sort each of these four subfiles. The array is then said to be 4-sorted. Similarly, we can define h-sorted. Notice that an array that is 1-sorted is sorted. 16 4-sorting Use Insertion sort with an increment of 4 A S O R T I N G E X A M P L E A S O R T I N G E X A M P L E A I O R T S N G E X A M P L E A I N R T S O G E X A M P L E A I N G T S O R E X A M P L E A I N G E S O R T X A M P L E A I N G E S O R T X A M P L E A I A G E S N R T X O M P L E A I A G E S N M T X O R P L E A I A G E S N M P X O R T L E A I A G E L N M P S O R T X E A I A G E L E M P S N R T X O 17 Implementation of h-sort public static <AnyType extends Comparable<? super AnyType>> void h_sort(AnyType[] a, int h) { for (int p = h; p < a.length; p++) { AnyType tmp = a[p]; int j = p; for ( ; j >= h && tmp.compareTo(a[j - h]) < 0; j -= h) a[j] = a[j - h]; a[j] = tmp; } } The code is obtained by replacing 1 by h in insertionSort. 18 Shellsort Shellsort uses h-sorting for a decreasing sequence of h-values, ending with h = 1. void shellsort(AnyType[] a) { for (int h = a.length / 2; h > 0; h = h == 2 ? 1 : (int) (h / 2.2)) h_sort(a, h); } 19 20 In the figure, elements spaced five and three apart are identically shaded. 21 Animation of Shellsort 22 (milliseconds) Shell’s increments: Start gaps at n/2 and halve until 1 is reached. Odd Gaps Only: As Shell’s increments, but add 1 whenever the gap becomes even. 23 Analysis of Shellsort Number of comparisons (for the increment sequence 1, 4, 13, 40,...): Best case: (n-1) + (n-4) + (n-13) + ... ≤ n log3n Worst case: less than n1.5 Average case: not known Two suggestions are O(n1.25) and O(n(log n)2) Number of moves: Best case: 0 Worst case: as for comparisons Average case: as for comparisons 24 Bubble Sort Repeatedly swap adjacent elements if they are in wrong order. boolean swapped; do { swapped = false; for (int i = 1; i < a.length; i++) { if (a[i - 1] > a[i]) { swap(a, i - 1, i); swapped = true; } } } while (swapped); Worst-case and average complexity: O(n2) Best case complexity: O(n) 25 Improved Bubble Sort All elements after the last swap are sorted, and do not need to be checked again. int n = a.length; do { int newn = 0; for (int i = 1; i < n; i++) { if (a[i - 1] > a[i]) { swap(a, i - 1, i); newn = i; } } n = newn; } while (n > 0); Worst-case and average complexity: O(n2) Best case complexity: O(n) 26 Mergesort Mergesort is a divide-and-conquer based sorting algorithm. The algorithm involves three steps: 1. If the number of items to sort is 0 or 1, then return. 2. Recursively sort the first and second halves separately. 3. Merge the two sorted halves into one sorted group. 27 Mergesort void mergeSort(Comparable[] a, int low, int high) { if (low < high) { int mid = (low + high) / 2; mergesort(a, low, mid); mergesort(a, mid + 1, high); merge(a, low, mid, high); } } ≤ ≤ low mid high 28 Linear-time merging of two sorted arrays 0 i M a: ≤ ≤ 0 j N b: ≤ ≤ 0 k M+N c: ≤ for (i = j = k = 0; k < M + N; k++) if (i == M) c[k] = b[j++]; else if (j == N) c[k] = a[i++]; else c[k] = a[i].compareTo(b[j]) < 0 ? a[i++] : b[j++]; 29 Merging a[low:mid] with a[mid+1:high] to a[low:high]: a: ≤ ≤ low mid mid+1 high Merge into b: b: ≤ low high Copy b to a: a: ≤ low high void merge(Comparable[] a, int low, int mid, int high) { int i = low, j = mid + 1; for (int k = low; k <= high; k++) if (i > mid) b[k] = a[j++]; else if (j > high) b[k] = a[i++]; else b[k] = a[i].compareTo(a[j]) < 0 ? a[i++] : a[j++]; for (int k = low; k <= high; k++) a[k] = b[k]; } 30 31 32 A S O R T I N G E X A M P L E A S O R T I N G E X A M P L E A S O R T I N G E X A M P L E A O R S T I N G E X A M P L E A O R S I T N G E X A M P L E A O R S I T G N E X A M P L E A O R S G I N T E X A M P L E A G I N O R S T E X A M P L E A G I N O R S T E X A M P L E A G I N O R S T E X A M P L E A G I N O R S T A E M X P L E A G I N O R S T A E M L L P E A G I N O R S T A E M L E L P A G I N O R S T A E E L M P X A A E E G I L M N O P R S T X 33 Animation of Mergesort 34 Call trees 16 8 8 4 4 4 4 2 2 2 2 2 2 2 2 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 21 10 11 5 5 5 6 2 3 2 3 2 3 3 3 1 1 1 2 1 1 1 2 1 1 1 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 35 Call tree There are about log2N levels Each level uses O(N) time 36 Evaluation of Mergesort Advantages: • insensitive to the input order • requires about N log2N comparisons for any array of N elements C(N) = 2C(N/2) + N, C(1) = 0 • is stable (preserves the input order of equal elements) • can be used for sorting linked lists • is suitable for external sorting Disadvantage: • requires (in practice) extra memory proportional to N 37 Quicksort! C.