Some New O(N2) Sorting Algorithms — Insertion Sort and Shell Sort The Insertion Sort template <class Comparable> void insertionSort( vector<Comparable> & a ) { for( int p = 1; p < a.size( ); p++ ) { Comparable tmp = a[ p ]; 6 10 24 36 12 int j; for( j = p; j > 0 && tmp < a[ j - 1 ]; j-- ) a[ j ] = a[ j - 1 ]; a[ j ] = tmp; } } The Shell Sort (Using Shell’s Poor Increments) template <class Comparable> void shellsort( vector<Comparable> & a ) { for( int gap = a.size( ) / 2; gap > 0; gap /= 2 ) for( int i = gap; i < a.size( ); i++ ) { Comparable tmp = a[ i ]; int j = i; for( ; j >= gap && tmp < a[ j - gap ]; j -= gap ) a[ j ] = a[ j - gap ]; a[ j ] = tmp; } } Are We Trading Off Ease of Coding for Slower Run Time By Using These Algorithms To Sort A Given Data Set? The Shell Sort Algorithm 1. Calculate gap as arraySize / 2, and ensure that elements separated by a gap distance are sorted. 2. Continue dividing gap by 2 until it becomes 1. Example Let’s sort the data set below using a Shell Sort : 8 6 0 3 2 7 5 1 9 4 0 3 2 8 6 1 9 4 2 3 6 4 7 5 9 8 2 3 4 5 6 7 8 9 after a gap = 5 : 7 5 after a gap = 2 : 0 1 after a gap = 1 : 0 1 Hey, three loops are not always worse than two. This is an O(n2) algorithm. We can make this sorting algorithm a lot better by using Hibbard’s gap sequence of : 1, 3, 7, …. 2k-1 Notice how this sequence produces lots of gaps that are prime numbers, as well as consecutive increments with no common factors. This will give us an O(n3/2) algorithm. CSC 245 Sorting Analysis Practice Problems 1. Show what the sequence 8, 5, 11, 13, 7, -19, 21, 2, 4 would look like after applying the pincer process of the QuickSort algorithm to partition this sequence. Use a pivot value of 8. 2. Sort the sequence 3, 1, 4, 1, 5, 9, 2, 6, 5 : a) Using the Insertion Sort Algorithm b) Using the Shell Sort Algorithm Show your array after each pass of the outermost for loop. 3. Show the result of running the Shell Sort Algorithm on the input 9, 8, 7, 6, 5, 4, 3, 2, 1 using Hibbard’s gaps of 7, 3, and 1. 4. Prove that the running time of the insertion sort algorithm is O(n) if all the elements are equal. Answers 1. 2. -19 5 4 2 7 8 21 13 11 a) Using the Insertion Sort Algorithm Original after after after after after after after after p p p p p p p p = = = = = = = = 1 2 3 4 5 6 7 8 3 1 4 1 5 9 2 6 5 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 4 4 3 3 3 2 2 2 1 1 4 4 4 3 3 3 5 5 5 5 5 4 4 4 9 9 9 9 9 5 5 5 2 2 2 2 2 9 6 5 6 6 6 6 6 6 9 6 5 5 5 5 5 5 5 9 b) Using the Shell Sort Algorithm (with poor gaps) Original 3 1 4 1 5 9 2 6 5 after gap = 4 after gap = 2 after gap = 1 3 2 1 1 1 1 2 3 2 1 1 3 5 4 4 9 6 5 4 5 5 6 9 6 5 5 9 3. Using the Shell Sort Algorithm (with Hibbard’s gaps) Original 9 8 7 6 5 4 3 2 1 after gap = 7 after gap = 3 after gap = 1 2 2 1 1 1 2 7 4 3 6 3 4 5 5 5 4 7 6 3 6 7 9 9 8 8 8 9 4. Prove that the running time of the insertion sort algorithm is O(n) if all the elements are equal. Proof. The boolean expression ( j > 0 && tmp < a[j – 1]) is false. So, the inner for loop terminates immediately and is never executed. So, our execution time is solely dependent on our outer loop. In this case, T(n) = n – 1. Therefore, we have O(n). The Insertion Sort template <class Comparable> void insertionSort( vector<Comparable> & a ) { for( int p = 1; p < a.size( ); p++ ) { Comparable tmp = a[ p ]; int j; for( j=p; j > 0 && tmp < a[ j - 1 ]; j-- ) a[ j ] = a[ j - 1 ]; a[ j ] = tmp; } } The Shell Sort (Using Shell’s Poor Increments) template <class Comparable> void shellsort( vector<Comparable> & a ) { for( int gap = a.size( ) / 2; gap > 0; gap /= 2 ) for( int i = gap; i < a.size( ); i++ ) { Comparable tmp = a[ i ]; int j = i; for(;j >= gap && tmp < a[ j-gap ];j -= gap ) a[ j ] = a[ j - gap ]; a[ j ] = tmp; } }