160 likes | 170 Views
Learn about standard sorting functions in computer science including key extraction, item exchange, and more. Explore sorting terminology and use generic functions for array sorting.
E N D
Department of Computer and Information Science,School of Science, IUPUI Sorting Dale Roberts, Lecturer Computer Science, IUPUI E-mail: droberts@cs.iupui.edu
Sorting Functions • Standard Functions • Item is the data type of items being sorted. • key() extracts the key from an item. • exch() exchanges two items. • less() returns true if first item is less than second. • compexch() compares and exchanges two items, if needed. • The sorts are written generically and assume that these functions are implemented.
Sorting Terminology • Terms • Sorting in memory is called internal sorting. • Sorting using tape or disk is called external sorting. • A sorting method is stable if it preserves the relative order of items with duplicate keys. • An adaptive sort uses information about the data to improve performance. A nonadaptive sort follows the same procedures regardless of the data.
Using #define to make sorts generic The following #define statements implement the required functions when sorting an array of integers. #include <iostream> #include <stdlib> template <class Item> void exch(Item &A, Item &B) { Item t = A; A = B; B = t; } template <class Item> void compexch(Item &A, Item &B) { if (B < A) exch(A, B); } template <class Item> void sort(Item a[], int l, int r) { for (int i = l+1; i <= r; i++) for (int j = i; j > l; j--) compexch(a[j-1], a[j]); } int main(int argc, char *argv[]) { int i, N = atoi(argv[1]), sw = atoi(argv[2]); int *a = new int[N]; if (sw) for (i = 0; i < N; i++) a[i] = 1000*(1.0*rand()/RAND_MAX); else { N = 0; while (cin >> a[N]) N++; } sort(a, 0, N-1); for (i = 0; i < N; i++) cout << a[i] << " "; cout << endl; } }
Selection Sort • Selection sort works by finding the smallest element in the array, and move that element the the front (by exchanging), and then finding the next smallest element and exchanging, and so forth. template <class Item> void selection(Item a[], int l, int r) { for (int i = l; i < r; i++) { int min = i; for (int j = i+1; j <= r; j++) if (a[j] < a[min]) min = j; exch(a[i], a[min]); } }
Selection Sort Demo • Selection Sort builds the final diagonal by exchanging the next-smallest element into position. The main cost of selection sorts is the comparisons required to find that element. Comparisons are not depicted in this representation except for a delay to make the time take for a comparison comparable to the cost of an exchange. The algorithm is slow at the beginning (because it has to scan through most of the array to find the next minimum) and fast at the end (because it has to scan through only a few elements).
Insertion Sort • Insertion sort is similar to how people sort playing cards. They pick up each card at a time, and insert the card into the proper position, making space for the new card between existing cards, if necessary. void sort(Item a[], int l, int r) { int i, j; for (i = l+1; i <= r; i++) for (j = i; j > l; j--) compexch(a[j-1], a[j]); }
Insertion Sort (improved) • This code is an improved version of insertion sort. First, it does a single assignment rather an exchange in the inner loop. Second, it moves the smallest key to the first position. Third, it simplifies the terminal condition for the inner loop (which it can only do because it made sure that less () becomes true before running off the end of the array. (how?) template <class Item> void insertion(Item a[], int l, int r) { int i; for (i = r; i > l; i--) compexch(a[i-1], a[i]); for (i = l+2; i <= r; i++) { int j = i; Item v = a[i]; while (v < a[j-1]) { a[j] = a[j-1]; j--; } a[j] = v; } } • These improvements yield half the running time for random inputs. Nothing comes for free. The improved efficiency in the critical section of code is a trade-off with the expense of ensuring that the minimum element is in the first position. Testing was required to determine if the trade-off was worth it. It was....
Insertion Sort Demo • Each demo is a dynamic representation of the algorithm in action, sorting an array a containing a permutation of the integers 1 through N. For each i, the array element a[i] is depicted as a black dot plotted at position (i, a[i]). Thus, the end result of each sort is a diagonal of black dots going from (1, 1) at the bottom left to (N, N) at the top right. Each time an element is moved, a green dot is left at its old position. Thus the moving black dots give a dynamic representation of the progress of the sort and the green dots give a history of the data-movement cost. • Insertion Sort maintains a ordered subarray that appears as a diagonal of black dots that moves from left to right sweeping up each new element that it encounters. Each new element is inserted into the diagonal.
Bubble Sort Bubble sort is normally the first sort learned by students. Scan the file from left to right, n times. Compare each element with its upper neighbor. Exchange if necessary. template <class Item> void bubble(Item a[], int l, int r) { for (int i = l; i < r; i++) for (int j = r; j > i; j--) compexch(a[j-1], a[j]); }
Bubble Sort Demo • Bubble Sort works like selection sort, but its cost is explicit in this representation because it uses exchanges (data movement) to move the minimum element from right to left, one position at a time.
Shellsort • Shellsort is an adaptation of insertion sort. The performance of insertion sort is limited because only adjacent elements are compared, which forces elements to wade through every intervening space to find its final resting place in the sort. • Significant time savings is realized when comparing items a greater distance apart. Instead of combining a[j] and a[j+1], compare a[j] and a[j+h] where h = 1, 4, 13, 40, 121, 364, 1093…. template <class Item> void shellsort(Item a[], int l, int r) { int h; for (h = 1; h <= (r-l)/9; h = 3*h+1) ; for ( ; h > 0; h /= 3) for (int i = l+h; i <= r; i++) { int j = i; Item v = a[i]; while (j >= l+h && v < a[j-h]) { a[j] = a[j-h]; j -= h; } a[j] = v; } }
Shellsort Demo • Shellsort is clearly much faster than the others, even (for example) for a file that is initially in reverse order or for a file that is ten times larger. • Shellsort Demo • Shellsort Demo - Reverse Order • Shellsort Demo - 10 times larger
Special sorts: Linked Lists • Sorting of linked listed is straightforward with selection sort with the following slight modication. Since it’s easier to insert at the head of the list, scan the list of the largest item, insert it at the head, then scan the list for the (2nd) largest item, insert it at the head, etc. The helper function, findmax() is used to find the node that points to the maximum element in the list. link listselection(link h) { node dummy(0); link head = &dummy, out = 0; head->next = h; while (head->next != 0) { link max = findmax(head), t = max->next; max->next = t->next; t->next = out; out = t; } return out; }
Acknowledgements • Elementary sorting methods are discussed in our Sedgewick text. Some of the demo are from the text website at princeton.edu.