Blame | Last modification | View Log | RSS feed
/* Written by: Ira Snyder* Started on: 05-20-2005* Due Date: 06-01-2005* CS331 Project #2** Changelog Follows:**/#include <stdio.h>#include <stdlib.h>#include <time.h>void mergesort (int array[], unsigned long size);void mergesort_rec (int A[], unsigned long min, unsigned long max);void merge (int A[], unsigned long asize, int B[], unsigned long bsize);void swap (int *left, int *right);void printarray (int array[], unsigned long size);void randomfill (int array[], unsigned long size);int partition (int array[], unsigned long left, unsigned long right);void copyarray (int src[], int dst[], unsigned long size);int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position);int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position);void startclock (void);void stopclock (void);void printtimetaken (char *funcname);/* global timeval for timing the function calls */struct timeval start_time, end_time, lapsed;int main (void){/* create new random seed */srand((unsigned)time(NULL));unsigned long size, kth_pos;int* array;int i;for (size=50; size<=3000; size+=50){if ( (array = (int*) malloc (size*sizeof(int))) == NULL){printf ("Ran out of memory at size=%d\n", size);exit(1);}/* fill the array with random values */randomfill (array, size);for (i=0; i<5; i++){if (i==0)kth_pos=0;else if (i==1)kth_pos=size/4;else if (i==2)kth_pos=size/2;else if (i==3)kth_pos=3*size/4;elsekth_pos=size-1;/* header */printf ("Running with size=%d (%.3fMB) kth_pos=%d...\n",size, (size*4.0)/(1024*1024), kth_pos);/* run method1 */startclock();printf ("%dth smallest (method1): %d -- ", kth_pos,kth_smallest_method1 (array, size, kth_pos));stopclock();printtimetaken("Method1");/* run method2 */startclock();printf ("%dth smallest (method2): %d -- ", kth_pos,kth_smallest_method2 (array, size, kth_pos));stopclock();printtimetaken("Method2");printf ("\n\n");}free (array);array = NULL;}return 0;}/* Mergesort an array* Sets up the correct parameters and hands off the work to* mergesort_rec()** Complexity: O(n*lgn)*/void mergesort (int array[], unsigned long size){mergesort_rec (array, 0, size-1);}/* The actual mergesort call */void mergesort_rec (int A[], unsigned long min, unsigned long max){unsigned long mid = (min+max)/2;unsigned long lowerCount = mid - min + 1;unsigned long upperCount = max - mid;if (max == min)return;mergesort_rec (A, min, mid);mergesort_rec (A, mid+1, max);merge (A+min, lowerCount, A+mid+1, upperCount);}/* merge two arrays together** Complexity: O(n)*/void merge(int A[], unsigned long asize, int B[], unsigned long bsize){unsigned long ai, bi, ci, i;int *C;unsigned long csize = asize+bsize;C = (int*) malloc (csize * sizeof(int));if (C == NULL){printf("Out of memory... Exiting\n");exit(1);}ai = 0;bi = 0;ci = 0;while ((ai < asize) && (bi < bsize)){if (A[ai] <= B[bi]){C[ci] = A[ai];ci++; ai++;}else{C[ci] = B[bi];ci++; bi++;}}if (ai >= asize)for (i = ci; i < csize; i++, bi++)C[i] = B[bi];else if (bi >= bsize)for (i = ci; i < csize; i++, ai++)C[i] = A[ai];for (i = 0; i < csize; i++)A[i] = C[i];free (C);}/* swap two values */void swap (int *left, int *right){int temp;temp = *left;*left = *right;*right = temp;}/* print out the contents of the array* used for debugging mainly*/void printarray (int array[], unsigned long size){unsigned long i;printf("Printing %d elements\n", size);for (i=0; i<size; i++)printf("%d ", array[i]);printf("\n");}/* fill the array with random numbers in* the range 0-32767*/void randomfill (int array[], unsigned long size){unsigned long i;for (i=0; i<size; i++)array[i] = rand() % 32768;}/* partition from quicksort* this partitions an array around the pivot value,* which is found in array[left].** All values less than the pivot are on the left* All values more than the pivot are on the right** Complexity: O(n)*/int partition (int array[], unsigned long left, unsigned long right){unsigned long i, last, pivot;pivot = array[left];last = left;for (i=left+1; i<=right; i++)if (array[i] < pivot){last++;swap (&array[last], &array[i]);}swap (&array[left], &array[last]);return last;}/* start the clock (for timing) */void startclock (void){gettimeofday(&start_time, NULL);}/* stop the clock (for timing) */void stopclock (void){gettimeofday(&end_time, NULL);}/* print the time taken, in milliseconds = seconds / 1000 */void printtimetaken (char *funcname){double total_usecs = (end_time.tv_sec-start_time.tv_sec) * 1000000.0+ (end_time.tv_usec-start_time.tv_usec);printf("%s : %.3lf milliseconds\n", funcname, total_usecs/1000.0);}/* copy the src[] to dst[] */void copyarray (int src[], int dst[], unsigned long size){unsigned long i;for (i=0; i<size; i++)dst[i] = src[i];}/* Find the kth smallest element in the array (starting from zero)** This uses the method of sorting the list, then picking* the correct element*/int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position){//int array[size];int *array;int retval;if ( (array = (int*) malloc (size*sizeof(int))) == NULL){printf ("Out of memory at size=%d\n", size);exit(1);}copyarray (src_array, array, size);mergesort (array, size);retval = array[position];free (array);array = NULL;return retval;}/* Find the kth smallest element in the array (starting from zero)** This uses the method of calling partiton() from quicksort, and* throwing out data that is unneeded*/int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position){//int array[size];int *array;int retval;unsigned long left = 0;unsigned long right = size-1;unsigned long pivotpos;if ( (array = (int*) malloc (size*sizeof(int))) == NULL){printf ("Out of memory at size=%d\n", size);exit(1);}copyarray (src_array, array, size);do{swap (&array[position], &array[left]);pivotpos = partition (array, left, right);if (pivotpos < position)left = pivotpos + 1;else /* pivotpos >= position) */right = pivotpos-1;}while (pivotpos != position);retval = array[position];free (array);array = NULL;return retval;}