Simple Sorting Algorithms I. Bubble Sort The strategy of the bubble sort is to place the largest vector value in the last vector slot, then seal off that slot from future consideration, & repeat the process. It causes a pass through the vector to compare adjacent pairs of keys. Whenever two keys are out of order with respect to each other the associated objects are interchanged. Example: First Pass Second Pass Third Pass Note the effect after such a pass through a list of data, we assured that one element comes in its right order (the last element). If one pass through a vector of n keys guarantees the key last in order appears in the appropriate position, then passing through the remaining n-1 entities using the same logic will guarantee that the key second to the last in order is in its appropriate position. Repeating the process for a total of n-1 passes ensures that all objects are in their appropriate positions. In general, on the kth pass through the vector, n-k comparisons of pairs must be made. Applying this to the above example: 4 elements (n=4) 3 passes kth pass n – k comparisons 2 pass 2 comparisons kth pass n – k + 1 not ordered & k – 1 2 pass 3 not ordered 1 ordered C++ Code ordered template < class element> void BubbleSort( apvector <element> &list, int n ) { int j, k; bool ExchangeMode; element temp; k = 0; ExchangeMode = true; // outer: while ( ( k < n – 1 ) && ExchangeMode ) //to control the { //# of passes through the vector. ExchangeMode = false; ++k; //inner: for ( j = 0 ; j < n-k ; ++j ) //to control the pairs of adjacent entries being compared if ( list[ j ] > list[ j+1 ] ) { temp = list[ j ]; list[ j ] = list[ j+1 ]; list[ j+1 ] = temp; ExchangeMode = true; } } } Note: In the kth pass, n – k + 1 keys still require ordering and k – 1 keys are in appropriate positions. Example: C Compare S Switch NS No Switch first pass second pass Note: ExchangeMode = false through out the inner loop, so the algorithm is done. Big-O Analysis of Bubble Sort - Bubble sort algorithm requires O( f(n) ) comparisons, find f(n) ? - If we assume that we have the worst case possible for a bubble sort, in which the ExchangeMode variable is always set to true so that an early exist is never made from the outer loop. - If we then consider the comparison of the top of the inner loop, we note that it will be executed first n – 1 times, then n – 2 times and so on down to one time for the final execution of the inner loop ( n-1 ) + ( n-2 ) + ( n-3 ) + . . . . + 1 = n( n – 1 ) / 2 O( n2 ) II. Selection Sort On the kth pass through the vector, it determines the positions of the smallest entry among: list[ k ], list[ k+1 ], . . . , list[ n-1 ] & then swaps this smallest entry with the kth entry, k is incremented by 1, & the process is repeated. Example: K=0 K=1 K=2 K=3 K=4 DAVE ARON ARON ARON ARON ARON TOM TOM BEV BEV BEV BEV PAM PAM PAM DAVE DAVE DAVE ARON DAVE DAVE PAM PAM PAM BEV BEV TOM TOM TOM SAM SAM SAM SAM SAM SAM TOM C++ Code: template < class element > void SelectionSort( apvector < element > &list, int n ) { int MinPosition; element temp; for ( int k=0 ; k < n-1 ; ++k ) { MinPosition = k; for ( int j = k+1 ; j < n ; ++j ) //to find the minimum entry & store its position if ( list[ j ] < list[ MinPosition ] ) MinPosition = j; if ( MinPosition != k ) { temp = list[ MinPosition ]; list[ MinPosition ] = list[ k ]; list[ k ] = temp; } } } Advantages: It reduces the number of data interchanges. Disadvantages: it does not allow an effective & automatic loop exit if the vector becomes ordered during an early pass. Example: First Pass Second Pass Third Pass Fourth Pass Big-O Analysis of selection sort Note that the first time the inner loop is executed, the comparison in the if statement will be made n – 1 times. Then it will be made n – 2 times, n - 3 times, & so on until one time. ( n-1 ) + ( n-2 ) + (n-3 ) + . . . + 1 = n( n-1 )/2 O( n2 ) in terms of comparisons. But selection sort offers better efficiency in the number of interchange of data in vector location. It guarantees O (n) interchanges (swaps), because the swap in selection sort occurs in the outer loop. Simple Searching Algorithms Search algorithms are algorithms that find a particular data item in a large collection of such items. I. Sequential Searching Algorithm Is to visit all items in the list in some arbitrary sequence until the desired item is found. C++ Code: template < class element, class keyType > bool SequentialSearch( const apvector< element > &list, int n, keyType target, element &object ) { int k = 0; bool found = false; while ( ( k < n ) && !found ) if ( list[ k ] == target ) found = true; else ++k; if ( found ) object = list[ k ]; return found; } Big-O Analysis of Sequential Search For unsuccessful invocation of the function, all numbers of records in the list (n) must be checked before we can conclude failure. Thus in terms of a big-O classification, the algorithm is clearly O(n) [ it is very slow]. II. Binary Search Algorithm The algorithm can be used if the list of objects with keys are maintained in physically sorted order LIST. The strategy of the binary search is to begin the search in the middle of the list & compare the data of that middle to the target. If it is not equal to target but less than the target then we have just to search from the middle + 1 to the end of the list (high), otherwise we have to search only from the beginning of the list (low) to the middle – 1, and so on. Example: C++ Code: template < class element , class keyType > bool BinarySearch( const apvector< element > &list, int n, keyType target, element &object ) { int low, middle, high; bool found = false; low = 0; high = n–1; while ( ( low <= high ) && !found ) { middle = ( low + high )/2; if ( list[ middle] == target ) found = true; else if ( list[ middle ] < target ) low = middle + 1; else high = middle – 1; } if ( found ) object = list[ middle ]; return found; } Example: When high & low pointers cross, conclude target cannot be found. Big-O Analysis of Binary Search Algorithm - The binary search continually halves the size of the list that must still be searched. - For a list of n items, the maximum number of times we would cut the list in half before finding the target item or declaring the search unsuccessful is (log2n ) + 1.