/* File: sortlist.c Sort the items of a linked list using Mergesort. */ #include #include #include #include "sortlist.h" /* Type definitions. We are sorting pointers to nodes */ typedef node *data ; typedef int index ; /* Private functions */ static void merge(data *, index, index, index, index) ; static void mergesort(data *, index, index) ; /* Global variable temp must be allocated the same amount of space as the array to be sorted */ static data *temp ; void SortList(list L) { index n, i ; data *A ; node *current ; n = L->count ; if (n == 0) return ; /* Allocate memory for sorting */ temp = (data *) malloc(n * sizeof(data)) ; A = (data *) malloc(n * sizeof(data)) ; if (temp == NULL || A == NULL) { printf("Could allocate temporary space for sorting\n") ; exit(1) ; } /* Load list into an array */ current = L->header.next ; i = 0 ; while(current != NULL) { A[i] = current ; current = current->next ; i++ ; } mergesort(A, 0, n-1) ; /* Reconnect linked list */ L->header.next = A[0] ; for(i = 0 ; i < n-1 ; i++) { A[i]->next = A[i+1] ; } A[n-1]->next = NULL ; free(A) ; free(temp) ; } static void merge(data *A, index low1, index high1, index low2, index high2) { index t, i1, i2 ; /* Sanity check */ assert(low2 == high1 + 1) ; /* while there are elements in both halves, copy the lowest one */ i1 = low1 ; i2 = low2 ; t = 0 ; while (i1 <= high1 && i2 <= high2) { if (strcmp(A[i1]->item, A[i2]->item) < 0) { temp[t] = A[i1] ; i1++ ; t++ ; } else { temp[t] = A[i2] ; i2++ ; t++ ; } } /* copy any remaining elements */ while (i1 <= high1) { temp[t] = A[i1] ; t++ ; i1++ ; } while (i2 <= high2) { temp[t] = A[i2] ; t++ ; i2++ ; } /* copy the now-sorted elements back into the original array */ for (t = low1; t <= high2; t++) { A[t] = temp[t - low1] ; } } static void mergesort(data *A, index low, index high) { index mid ; if (low >= high) return ; mid = (low + high)/2 ; mergesort(A, low, mid) ; mergesort(A, mid + 1, high) ; merge(A, low, mid, mid + 1, high) ; }