#include "pa03.h" #include #include /** * Read a file of integers. * * Arguments: * * filename: the name of a file that contains a list of integers (one * per line) * * numberOfIntegers: pointer to store the number of integers in the * file. You need to update the value stored at the address which is * the pointer's value * * Returns: * * a array of integers from the file, or NULL if *any* error is * encountered. * * You do NOT know how many integers are in the file until you have * read it. Once you know how many integers there are, you can modify * the "numberOfIntegers" variable. (Note that this is a pointer, not * an integer) You must allocate memory to store the integers. * * Once memory is allocated to store the integers, you will need to * re-read the values from the file. To do this, you must reset the * file pointer to the beginning of the file using the function * "fseek". * * You should not use rewind (if you have learned it somewhere). The * difference of rewind and fseek is that rewind does not tell you * whether it fails. * * One way to read integeres is to use the "fscanf" function. It is * easier than reading one character at a time by using fgetc. * * You must use malloc in this function. * * Some old books encourage readers to type cast in front of malloc, * something like * * int * ptr = (int *) malloc(sizeof(int) * size); * * Type cast is no longer needed and in fact is discouraged now. You * should *NOT* type cast malloc. It is discouraged even though it is * not wrong. * * The allocated memory will be released in pa03.c. You do not need to * worry about releasing memory. * * You will receive zero if you allocate a large array whose size is * independent of the number of integers in the file. For example, if * you write this * * int array[10000]; * * */ int * readIntegers(const char * filename, int * numberOfIntegers) { FILE *file; // file pointer int *contents; // array to be returned int val; // temp variable int i = 0; // incrementor variable file = fopen(filename, "r"); // open file if(file == NULL) // return NULL on file read error return NULL; while(fscanf(file, "%d", &val) == 1) // count number if integers in file { i++; } *numberOfIntegers = i; // set numberOfIntegers if(!fseek(file, 0, SEEK_SET) == 0) // reset file pointer return NULL; // return NULL on pointer reset error contents = malloc(*numberOfIntegers * sizeof(int)); // allocate memory for(i = 0; i < *numberOfIntegers; i++) // sets contents' values { fscanf(file, "%d", &val); contents[i] = val; } if(!fclose(file) == 0) // close file return NULL; // return NULL on file close error return contents; // return array of data read from file } /** * Sort an (ascending) array of integers * * Arguments: * arr The array to search * length Number of elements in the array * * Uses "quicksort" to sort "arr". Use the first element of the array * as the pivot. * * Your solution MUST use recursive function (or functions) * * quicksort works in the following way: * * find an element in the array (this element is called the * pivot). * * rearrange the array's elements into two parts: the part smaller * than this pivot and the part greater than this pivot; make the pivot * the element between these two parts * * sort the first and the second parts separately by repeating the * procedure described above * * You will receive no point if you use any other sorting algorithm. * You cannot use selection sort, merge sort, or bubble sort. * * Some students are fascinated by the name of bubble sort. In * reality, bubble sort is rarely used because it is slow. It is a * mystery why some students (or even professors) like bubble sort. * Other than the funny name, bubble sort has nothing special and is * inefficient, in both asymptotic complexity and the amount of data * movement. There are many algorithms much better than bubble sort. * You would not lose anything if you do not know (or forget) bubble * sort. * */ void q_sort(int *arr, int start, int end) // helper function for sort { if(end - start < 2) // condition to end recursion return; int pivot = start; // set initial pivot index int val; // create temporary variable used to swap values int i = start; // incrementor variable int j = end; // decrementor variable while(i < j) // prevent i and j from over-lapping { while(arr[i] < arr[pivot] && i <= end) { i++; // find index of value less than pivot value } while (arr[j] > arr[pivot] && j >= start) { j--; // find index of value greater than pivot value } val = arr[i]; // swap value at i with value at j arr[i] = arr[j]; arr[j] = val; } // repeat for all values i < j, i.e. one pass q_sort(arr, start, j-1); // repeat for sub array of smaller indices q_sort(arr, j+1, end); // repeat for sub array of larger indices } void sort(int * arr, int length) { q_sort(arr, 0, length - 1); // call helper function } /** * Use binary search to find 'key' in a sorted array of integers * * Arguments: * * arr The array to search. Must be sorted ascending. You do not need * to check. This array is from the result of your sort * function. Make sure your sort function is correct before you * start writing this function. * * length Number of elements in the array * key Value to search for in arr * * Returns: * The index of 'key', or -1 if key is not found. * * Since the array is sorted, you can quickly discard many elements by * comparing the key and the element at the center of the array. If * the key is the same as this element, you have found the index. If * the key is greater than this element, you can discard the first * half of the array. If the key is smaller, you can discard the * second half of the array. Now you have only half of the array to * search. Continue this procedure until either you find the index or * it is impossible to find a match. * * Your solution MUST use recursive function (or functions) * * Don't forget that arrays are 'zero-indexed'. Also, you must * use a binary search to pass this question. * * You will receive no point if you do the following because it is not * binary search. This is called linear search because it checks * every element. * * int ind; * for (ind = 0; ind < length; ind ++) * { * if (arr[ind] == key) * { * return ind; * } * } * return -1; */ int b_search(int * arr, int start, int end, int key) { if (start > end) // condition to end recursion return -1; int val = (start + end) / 2; // set val to halfway point in arr if(arr[val] == key) // return index if key is found return val; if(arr[val] < key) // rerun function if key is in top half return b_search(arr, val + 1, end, key); if(arr[val] > key) // rerun function if key is in bottom half return b_search(arr, start, val - 1, key); return -1; // return -1 if key is not found } int search(int * arr, int length, int key) { return b_search(arr, 0, length - 1, key); // call helper function }