answer03.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "pa03.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. /**
  5. * Read a file of integers.
  6. *
  7. * Arguments:
  8. *
  9. * filename: the name of a file that contains a list of integers (one
  10. * per line)
  11. *
  12. * numberOfIntegers: pointer to store the number of integers in the
  13. * file. You need to update the value stored at the address which is
  14. * the pointer's value
  15. *
  16. * Returns:
  17. *
  18. * a array of integers from the file, or NULL if *any* error is
  19. * encountered.
  20. *
  21. * You do NOT know how many integers are in the file until you have
  22. * read it. Once you know how many integers there are, you can modify
  23. * the "numberOfIntegers" variable. (Note that this is a pointer, not
  24. * an integer) You must allocate memory to store the integers.
  25. *
  26. * Once memory is allocated to store the integers, you will need to
  27. * re-read the values from the file. To do this, you must reset the
  28. * file pointer to the beginning of the file using the function
  29. * "fseek".
  30. *
  31. * You should not use rewind (if you have learned it somewhere). The
  32. * difference of rewind and fseek is that rewind does not tell you
  33. * whether it fails.
  34. *
  35. * One way to read integeres is to use the "fscanf" function. It is
  36. * easier than reading one character at a time by using fgetc.
  37. *
  38. * You must use malloc in this function.
  39. *
  40. * Some old books encourage readers to type cast in front of malloc,
  41. * something like
  42. *
  43. * int * ptr = (int *) malloc(sizeof(int) * size);
  44. *
  45. * Type cast is no longer needed and in fact is discouraged now. You
  46. * should *NOT* type cast malloc. It is discouraged even though it is
  47. * not wrong.
  48. *
  49. * The allocated memory will be released in pa03.c. You do not need to
  50. * worry about releasing memory.
  51. *
  52. * You will receive zero if you allocate a large array whose size is
  53. * independent of the number of integers in the file. For example, if
  54. * you write this
  55. *
  56. * int array[10000];
  57. *
  58. *
  59. */
  60. int * readIntegers(const char * filename, int * numberOfIntegers)
  61. {
  62. FILE *file; // file pointer
  63. int *contents; // array to be returned
  64. int val; // temp variable
  65. int i = 0; // incrementor variable
  66. file = fopen(filename, "r"); // open file
  67. if(file == NULL) // return NULL on file read error
  68. return NULL;
  69. while(fscanf(file, "%d", &val) == 1) // count number if integers in file
  70. {
  71. i++;
  72. }
  73. *numberOfIntegers = i; // set numberOfIntegers
  74. if(!fseek(file, 0, SEEK_SET) == 0) // reset file pointer
  75. return NULL; // return NULL on pointer reset error
  76. contents = malloc(*numberOfIntegers * sizeof(int)); // allocate memory
  77. for(i = 0; i < *numberOfIntegers; i++) // sets contents' values
  78. {
  79. fscanf(file, "%d", &val);
  80. contents[i] = val;
  81. }
  82. if(!fclose(file) == 0) // close file
  83. return NULL; // return NULL on file close error
  84. return contents; // return array of data read from file
  85. }
  86. /**
  87. * Sort an (ascending) array of integers
  88. *
  89. * Arguments:
  90. * arr The array to search
  91. * length Number of elements in the array
  92. *
  93. * Uses "quicksort" to sort "arr". Use the first element of the array
  94. * as the pivot.
  95. *
  96. * Your solution MUST use recursive function (or functions)
  97. *
  98. * quicksort works in the following way:
  99. *
  100. * find an element in the array (this element is called the
  101. * pivot).
  102. *
  103. * rearrange the array's elements into two parts: the part smaller
  104. * than this pivot and the part greater than this pivot; make the pivot
  105. * the element between these two parts
  106. *
  107. * sort the first and the second parts separately by repeating the
  108. * procedure described above
  109. *
  110. * You will receive no point if you use any other sorting algorithm.
  111. * You cannot use selection sort, merge sort, or bubble sort.
  112. *
  113. * Some students are fascinated by the name of bubble sort. In
  114. * reality, bubble sort is rarely used because it is slow. It is a
  115. * mystery why some students (or even professors) like bubble sort.
  116. * Other than the funny name, bubble sort has nothing special and is
  117. * inefficient, in both asymptotic complexity and the amount of data
  118. * movement. There are many algorithms much better than bubble sort.
  119. * You would not lose anything if you do not know (or forget) bubble
  120. * sort.
  121. *
  122. */
  123. void q_sort(int *arr, int start, int end) // helper function for sort
  124. {
  125. if(end - start < 2) // condition to end recursion
  126. return;
  127. int pivot = start; // set initial pivot index
  128. int val; // create temporary variable used to swap values
  129. int i = start; // incrementor variable
  130. int j = end; // decrementor variable
  131. while(i < j) // prevent i and j from over-lapping
  132. {
  133. while(arr[i] < arr[pivot] && i <= end)
  134. {
  135. i++; // find index of value less than pivot value
  136. }
  137. while (arr[j] > arr[pivot] && j >= start)
  138. {
  139. j--; // find index of value greater than pivot value
  140. }
  141. val = arr[i]; // swap value at i with value at j
  142. arr[i] = arr[j];
  143. arr[j] = val;
  144. } // repeat for all values i < j, i.e. one pass
  145. q_sort(arr, start, j-1); // repeat for sub array of smaller indices
  146. q_sort(arr, j+1, end); // repeat for sub array of larger indices
  147. }
  148. void sort(int * arr, int length)
  149. {
  150. q_sort(arr, 0, length - 1); // call helper function
  151. }
  152. /**
  153. * Use binary search to find 'key' in a sorted array of integers
  154. *
  155. * Arguments:
  156. *
  157. * arr The array to search. Must be sorted ascending. You do not need
  158. * to check. This array is from the result of your sort
  159. * function. Make sure your sort function is correct before you
  160. * start writing this function.
  161. *
  162. * length Number of elements in the array
  163. * key Value to search for in arr
  164. *
  165. * Returns:
  166. * The index of 'key', or -1 if key is not found.
  167. *
  168. * Since the array is sorted, you can quickly discard many elements by
  169. * comparing the key and the element at the center of the array. If
  170. * the key is the same as this element, you have found the index. If
  171. * the key is greater than this element, you can discard the first
  172. * half of the array. If the key is smaller, you can discard the
  173. * second half of the array. Now you have only half of the array to
  174. * search. Continue this procedure until either you find the index or
  175. * it is impossible to find a match.
  176. *
  177. * Your solution MUST use recursive function (or functions)
  178. *
  179. * Don't forget that arrays are 'zero-indexed'. Also, you must
  180. * use a binary search to pass this question.
  181. *
  182. * You will receive no point if you do the following because it is not
  183. * binary search. This is called linear search because it checks
  184. * every element.
  185. *
  186. * int ind;
  187. * for (ind = 0; ind < length; ind ++)
  188. * {
  189. * if (arr[ind] == key)
  190. * {
  191. * return ind;
  192. * }
  193. * }
  194. * return -1;
  195. */
  196. int b_search(int * arr, int start, int end, int key)
  197. {
  198. if (start > end) // condition to end recursion
  199. return -1;
  200. int val = (start + end) / 2; // set val to halfway point in arr
  201. if(arr[val] == key) // return index if key is found
  202. return val;
  203. if(arr[val] < key) // rerun function if key is in top half
  204. return b_search(arr, val + 1, end, key);
  205. if(arr[val] > key) // rerun function if key is in bottom half
  206. return b_search(arr, start, val - 1, key);
  207. return -1; // return -1 if key is not found
  208. }
  209. int search(int * arr, int length, int key)
  210. {
  211. return b_search(arr, 0, length - 1, key); // call helper function
  212. }