570 likes | 951 Views
Sorting – Insertion Sort. Assume that the elements are numbered 0…size-1 Examine element at position x. “Insert” it in the correct sorted order in the list from 0 to x-1. Repeat until x = size-1. Sorting – Insertion Sort. 8 6 34 2 51 32 21 original
E N D
Sorting – Insertion Sort • Assume that the elements are numbered 0…size-1 • Examine element at position x. “Insert” it in the correct sorted order in the list from 0 to x-1. • Repeat until x = size-1
Sorting – Insertion Sort 8 6 34 2 51 32 21 original 6 8 34 2 51 32 21 pass 1 6 8 34 2 51 32 21 pass 2 2 6 8 34 51 32 21 pass 3 2 6 8 34 51 32 21 pass 4 2 6 8 32 34 51 21 pass 5 2 6 8 21 32 34 51 pass 6
Sorting – Insertion Sort template <class T> void insertionSort( T ar[], int size ) { int j; for( int x = 1; x < size; x++ ) { T temp = ar[ x ]; for( j = x; j > 0 && temp < ar[ j – 1 ]; j-- ) ar[ j ] = ar[ j-1 ]; ar[ j ] = temp; } }
Sorting – Insertion Sort Each loop executes at most N (or size) times, therefore this sort is O(N2). If the array is array is already sorted, then this algorithm is O(N).
Sorting – Selection Sort • Assume the elements are numbered from 0…size1 • Search the entire list and “select” the element with the smallest value. Swap it with the element at the top of the list. • Repeat until size-1 passes have been made through the list
Sorting – Selection Sort 8 6 34 2 51 32 21 original 2 6 34 8 51 32 21 pass 1 2 6 34 8 51 32 21 pass 2 2 6 8 34 51 32 21 pass 3 2 6 8 21 51 32 34 pass 4 2 6 8 21 32 51 34 pass 5 2 6 8 21 32 34 51 pass 6
Sorting – Selection Sort template <class T> void selectionSort( T ar[], int size ) { for( int top = 0; top < size; top++ ) { int ssf = top; for( int j = top; j < size; j++ ) if( ar[ j ] < ar[ ssf ] ) ssf = j; swap( ar[ top ], ar[ ssf ] ); } }
Sorting – Selection Sort Each loop executes at most N (or size) times, therefore this sort is O(N2). If the array is array is already sorted, then this algorithm is still O(N2).
Sorting – Bubble Sort • Assume that the elements are numbered 0…size-1 • Examine elements at positions x and x+1. Put them in ascending order. Now examine the elements at positions x+1 and x+2. Put them in ascending order. Repeat until the end of the list has been reached. • Repeat the above process but limit the size of the list by 1
Sorting – Bubble Sort 8 6 34 2 51 32 21 original 6 8 34 2 51 32 21 pass 1 6 8 34 2 51 32 21 6 8 2 34 51 32 21 6 8 2 34 51 32 21 6 8 2 34 32 51 21 6 8 2 34 32 21 51
Sorting – Bubble Sort 6 8 2 34 32 21 51 6 8 2 34 32 21 51 pass 2 6 2 8 34 32 21 51 6 2 8 34 32 21 51 6 2 8 32 34 21 51 6 2 8 32 21 34 51 Repeat the process until the list is sorted
Sorting – Bubble Sort template <class T> void bubbleSort( T ar[], int size ) { int end = size - 1; for ( bool isSwap = true; isSwap && end > 0; end -- ) { isSwap = false; for( int i = 0, j = 1; j <= end; i++, j++ ) { if( ar[ i ] > ar[ j ] ) { isSwap = true; swap( ar[ i ], ar[ j ] ); } } } }
Sorting – Bubble Sort Each loop executes at most N (or size) times, therefore this sort is O(N2). If the array is array is already sorted, then this algorithm is still O(N2).
Sorting – Shell Sort • Assume that the elements are numbered 0…size-1 • Examine and sort every nth element of the list. Continue the process with the (n+1)th elements of the list. Continue until all of the elements have been examined once. • Decrease the value of n. • Repeat the process until n becomes 1 • Because the value of n is diminishing with each pass through the algorithm, this is known as a diminishing increment sort.
Sorting – Shell Sort • Initial n value: size / 2 • Subsequent n values: n / 2 • 8 6 34 2 51 32 21 original • 26328513421 n = 3 • 2 6 32 8 51 34 21 • 2 6 8 21 32 34 51 n = 1
Sorting – Shell Sort template <class T> void shellSort( T ar[], int size ) { int j; for ( int gap = size / 2; gap > 0; gap /= 2 ) for( int i = gap; i < size; i++ ) { T temp = ar[ i ]; for( j = i; j >= gap && temp < ar[j–gap]; j -= gap ) ar[ j ] = ar[ j – gap ]; ar[ j ] = temp; } }
Sorting – Shell Sort The running time of this sort depends on the choice of n. Using the n calculation that was presented, this is an O(N2) algorithm. The algorithm can be made more effective by using increments 1, 3, 7, …, 2k-1. This sequence will keep consecutive elements from having common factors. This new algorithm is O(N3/2).
Sorting – Heap Sort • Heapify the list • Swap the element at the beginning of the list with the element at the end of the list • Make the list 1 element shorter • Heapify the new smaller list by continually percolating down. Repeat the process until the entire list is sorted. • This will produce a list that is sorted in descending order.
Sorting – Heap Sort 8 6 34 2 51 32 21 original
Sorting – Heap Sort The list is heapified. Swap minimum item with last element.
Sorting – Heap Sort The list is heapified. Swap minimum item with “last” element.
Sorting – Heap Sort The remaining trees are the results after they have been heapified followed by the result after swapping.
Sorting – Heap Sort The remaining trees are the results after they have been heapified followed by the result after swapping.
Sorting – Heap Sort The remaining trees are the results after they have been heapified followed by the result after swapping.
Sorting – Heap Sort The remaining trees are the results after they have been heapified followed by the result after swapping.
Sorting – Heap Sort template <class T> void heapSort( T ar[], int size ) { for ( int i = ( size – 1 ) / 2; i > 0; i-- ) percDown( ar, i, size - 1 ); for( int j = size - 1; j > 1; j-- ) { swap( ar[ 1 ], ar[ j ] ); percDown( ar, 1, j - 1 ); } }
Sorting – Heap Sort This is a 2N log N – O(N) algorithm. Proof is in the book.
Sorting – Merge Sort • Divide the list in half • Sort the left half of the list • Sort the right half of the list • Merge the two sorted halves into one large list
Sorting – Merge Sort 8 6 34 2 51 32 21 original 8 6 34 251 32 21 2 6 8 3421 32 51 2 6 821 323451
Sorting – Merge Sort template <class T> void mergeSort( T ar[], int size ) { T *tempArray = new T[ size ]; mergeSort( ar, tempArray, 0, size – 1 ); } template <class T> void mergeSort( T ar[], T temp[], int left, int right ) { if( left < right ) { int center = ( left + right ) / 2; mergeSort( ar, temp, left, center ); mergeSort( ar, temp, center + 1, right ); merge(ar, temp, left, center + 1, right );l } }
Sorting – Merge Sort template <class T> void merge( T ar[], T temp[], int lPos, int rPos, int rEnd ) { int lEnd = rPos – 1, tempPos = lPos, numElem = rEnd – lPos + 1; while( lPos <= lEnd && rPos <= rEnd ) if( ar[ lPos ] <= ar[ rPos ] ) temp[ tempPos++ ] = ar[ lPos++ ]; else temp[ tempPos++ ] = ar[ rPos++ ]; while( lPos <= lEnd ) temp[ tempPos++ ] = ar[ lPos++ ]; while( rPos <= rEnd ) temp[ tempPos++ ] = ar[ rPos++ ]; for( int i = 0; i < numElem; i++, rEnd-- ) ar[ rEnd ] = temp[ rEnd ]; }
Sorting – Merge Sort Since the routine is recursive, we must come up with a recurrence relation to figure the running time. For a list of size 1, the time to merge sort is constant. T(1) = 1 Otherwise, each recursive call is dealing with half of the list ( T(n/2) ), plus the time to merge, which is linear ( N). T(n) = T(n/2) + T(n/2) + n = 2T(n/2) + n
Sorting – Merge Sort T(n) = 2T(n/2) + n T(n/2) = 2T(n/2/2) + n/2 = 2T(n/4) + n/2 2T(n/2) = 4T(n/4) + n 2T(n/2) + n = 4T(n/4) + 2n T(n) = 2T(n/2) + n = 4T(n/4) + 2n In general: T(n) = 2kT(n/2k) + kn Solve for k: n/2k = 1 n = 2k log n = k
Sorting – Merge Sort In general: T(n) = 2kT(n/2k) + kn Substitute k = log n in the general equation: T(n) = 2log n T(n/2log n) + n log n = n T(n/n) + n log n = n * T(1) + n log n = n * 1 + n log n = n + n log n O(n + n log n) => O(n log n)
Sorting – Quick Sort • This algorithm is a divide and conquer algorithm. • Divide the list into three segments: left, right, and middle • The middle segment consists of one element, which is known as the pivot • The left segment consists of elements that are smaller than the pivot • The right segment consists of elements that are larger than the pivot
Sorting – Quick Sort Initial Psuedocode: if size of list is greater than 1 select the pivot partition remaining elements into left and right quicksort(left) quicksort(right) endif Quicksort the following list:
Sorting – Quick Sort Lets pick 65 as the pivot. Then partitioning the list around the pivot results in: Quicksort both the left and right segments:
Sorting – Quick Sort • Picking the pivot: • Let the first element be the pivot • This is okay if the items in the list are random. If the list is sorted or in reverse order, this is a poor choice because all of the elements will end up in either the left or right segment. • Choose the pivot randomly • This option is usually pretty safe, except for the fact that the random number generation is expensive.
Sorting – Quick Sort • Picking the pivot: • Median of three • Find the first, middle and last element in the array. Use the median of the three as the pivot.
Sorting – Quick Sort • Partitioning the list: • Swap the pivot element with the last element. • 8 1 4 9 6 3 5 2 7 0 • 8 1 4 9 0 3 5 2 7 6 • Set i to the first element and j to the next to last element. • 8 1 4 9 0 3 5 2 7 6 • i j
Sorting – Quick Sort • Partitioning the list: • Move i to the right until it refers to an element that is larger than the value at the pivot. • 8 1 4 9 0 3 5 2 7 6 • i j • Move j to the left until it refers to an element that is smaller than the value at the pivot. • 8 1 4 9 0 3 5 2 7 6 • i j
Sorting – Quick Sort • Partitioning the list: • If i is to the left of j, swap the elements at positions i and j. • 8 1 4 9 0 3 5 2 7 6 • i j • 2 1 4 9 0 3 5 8 7 6 • i j
Sorting – Quick Sort • Partitioning the list: • Continue the process until i and j meet or i surpasses j. • 2 1 4 9 0 3 5 8 7 6 • i j • 2 1 4 5 0 3 9 8 7 6 • j i • Swap the pivot element and the element at position i. • 2 1 4 5 0 3 6 8 7 9
Sorting – Quick Sort • Partitioning the list: • Continue the process until i and j meet or i surpasses j. • 2 1 4 9 0 3 5 8 7 6 • i j • 2 1 4 5 0 3 9 8 7 6 • j i • Swap the pivot element and the element at position i. • 2 1 4 5 0 3 6 8 7 9
Sorting – Quick Sort template <class T> int partition( T ar[], int left, int right ) { int center = ( left + right ) / 2, pivot = median( ar, left, center, right ); int i = left, j = right - 1; while( i < j ) { while( ar[ j ] > pivot ) j--; while( ar[ i ] <= pivot && i < j ) i++; if( i < j ) swap( ar[ i ], ar[ j ] ); } swap( ar[ i ], pivot ); return i; }
Sorting – Quick Sort template <class T> void quickSort( T ar[], int size ) { quickSort( ar, 0, size – 1 ); } template <class T> void quickSort( T ar[], int left, int right ) { if( left < right ) { int pivotPos = partition( ar, left, right ); quickSort( ar, left, pivotPos – 1 ); quickSort( ar, pivotPos + 1, right ); } }
Sorting – Quick Sort Quick sort is recursive therefore we need a recurrence relation. Running time is equal to running time of the two recursive calls plus the linear time for partitioning: T(n) = T(i) + T(n – i – 1) + cn T(n) = 1 n <= 1 where i is the size of the left segment.