| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #include "pa03.h"
- #include <stdio.h>
- #include <stdlib.h>
- /**
- * 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
- }
|