#include #include #include /* for the measuring of running-time */ /* Merge function - note use of k++, i++ sitting *within* other * expressions. This is a very delicate use of k++ (big contrast * to if we had used ++k). Please make sure you are ok with * the details of these (within expression) increments. */ void merge(int a[], int b[], int c[], int m, int n) { int i=0, j=0, k=0; while (i < m || j < n) { /* In the following condition, if j >= n, C knows the condition is true, and it *doesn't* check the rest, so it doesn't matter that b[j] is off the end of the array. So the order of these is important */ if (j >= n || (i < m && a[i] <= b[j])) { /* either we've run out of b, or the smallest elt is in a */ c[k++] = a[i++]; } else { /* either we've run out of a, or the smallest elt is in b */ c[k++] = b[j++]; } } } /* returns 1 on success, 0 on failure */ int mergesort(int key[], int n){ int j, *w; if (n <= 1) { return 1; } /* base case, sorted */ w = calloc(n, sizeof(int)); /* space for temporary array */ if (w == NULL) { return 0; } /* calloc failed */ j = n/2; /* do the subcalls and check they succeed */ if ( mergesort(key, j) && mergesort(key+j, n-j) ) { merge(key, key+j, w, j, n-j); for (j = 0; j < n; ++j) key[j] = w[j]; free(w); /* Free up the dynamic memory no longer in use. */ return 1; } else { /* a subcall failed */ free(w); return 0; } } /* Function to write-out the contents of key[] in appropriate form. */ void wrt(int key[], int sz) { int i; for (i = 0; i < sz; ++i) printf("%4d%s", key[i], ((i < sz -1) ? "" : "\n")); } int main(void) { int i, sz, *key = NULL, flag; double start, stop, t; printf("Input desired size of array: "); scanf("%d", &sz); printf("\n"); key = calloc(sz, sizeof(int)); /* Make array of this size */ if (key != NULL) { /* check there was space */ for(i = 0; i < sz; i++) /* Fill array: */ key[i] = rand() % 1000; /* rand() returns 1 random int */ if(sz < 20) { /* For small arrays, show before-and-after array on the screen */ printf("Before mergesort: \n"); wrt(key, sz); flag = mergesort(key, sz); if (flag) { printf("After mergesort: \n"); wrt(key, sz); } } else { /* For large arrays, our interest is in the runtime statistics. */ start = (double)clock(); flag = mergesort(key, sz); stop = (double)clock(); t = (stop-start)/CLOCKS_PER_SEC; if (flag) printf("Time on array of length %d was %f sec.\n", sz, t); else printf("Not enough space.\n"); } free(key); } else printf("Trouble allocating space for that many integers.\n"); return EXIT_SUCCESS; }