answer08.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include "pa08.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. /*
  5. * Create a single instance of a sparse array tree node with a specific
  6. * index and value. This Sparse array will be implemented by a binary tree.
  7. *
  8. * Arguments:
  9. * index the index to be stored in the node
  10. * value the value to be stored in the node
  11. *
  12. * returns:
  13. * SparseNode * the pointer points to the node just constructed
  14. *
  15. * This is a constructor function that allocates
  16. * memory for a sparse array tree node, and it copies the integer values, and sets the
  17. * subtree pointers to NULL.
  18. */
  19. SparseNode *SparseNode_create(int index, int value)
  20. {
  21. if(index < 0 || value == 0) // check that values are reasonable
  22. return NULL;
  23. SparseNode *temp;
  24. temp = malloc(sizeof(SparseNode));
  25. temp->left = NULL; // initialize values
  26. temp->right = NULL;
  27. temp->index = index;
  28. temp->value = value;
  29. return temp;
  30. }
  31. /* Add a particular value into a sparse array tree on a particular index.
  32. *
  33. * Arguments:
  34. * *array the root node of the sparse array tree
  35. * index the index to be stored in the node
  36. * value the value to be stored in the node
  37. *
  38. * returns:
  39. * SparseNode * the pointer points to the root node of the modified sparse
  40. * array tree
  41. *
  42. * The sparse array tree uses the index as a key in a binary search tree.
  43. * If the index does not exist, create it.
  44. * If the index exists, REPLACE the value to the new one. Use the index to
  45. * determine whether to go left or right in the tree (smaller index
  46. * values than the current one go left, larger ones go right).
  47. */
  48. SparseNode * SparseArray_insert ( SparseNode * array, int index, int value )
  49. {
  50. if(index < 0 || value == 0) // check that values are reasonable
  51. return array;
  52. if(array == NULL) // create array if it does not exist
  53. return SparseNode_create(index, value); // return new array
  54. if(index < array->index) // recurse if key is low
  55. array->left = SparseArray_insert(array->left, index, value);
  56. else
  57. if(index > array->index) // recurse if key is high
  58. array->right = SparseArray_insert(array->right, index, value);
  59. else // set value if array->index matches key
  60. array->value = value;
  61. return array; // return unmodified array head
  62. }
  63. /* Build a sparse array tree from given indices and values with specific length.
  64. *
  65. * Arguments:
  66. * index* a pointer points to the start position of the index array
  67. * value* a pointer points to the start position of the value array
  68. * length the size of both array
  69. *
  70. * returns:
  71. * SparseNode * the pointer points to the root node of sparse array tree
  72. * just constructed
  73. *
  74. * It returns a sparse array tree.
  75. * You need to insert tree nodes in order
  76. *
  77. * (the first sparse array node contains indices[0] and values[0], second node
  78. * contains indices[1] and values[1]. Basically, each tree node is constructed
  79. * with each pair in indices and values array. In other words, elements of
  80. * indices and values with the same index should go into the same node.)
  81. */
  82. SparseNode *SparseArray_build(int * indicies, int * values, int length)
  83. {
  84. SparseNode *temp = NULL;
  85. int i = 0;
  86. for(i = 0; i < length; i++) // for loop for inserting array
  87. {
  88. temp = SparseArray_insert(temp, indicies[i], values[i]);
  89. }
  90. return temp;
  91. }
  92. /* Destroy an entire sparse array tree.
  93. *
  94. * Arguments:
  95. * *array the root node of a sparse array tree
  96. *
  97. * returns:
  98. * void
  99. *
  100. * traversing the binary tree in postorder. Use the
  101. * SparseNode_destroy () function to destroy each node by itself.
  102. */
  103. void SparseArray_destroy ( SparseNode * array )
  104. {
  105. if(array != NULL) // recurse down each child
  106. {
  107. SparseArray_destroy(array->left);
  108. SparseArray_destroy(array->right);
  109. free(array); // remove parent after children are destroyed
  110. }
  111. }
  112. /* Retrieve the smallest index in the sparse array tree.
  113. *
  114. * Arguments:
  115. * *array the root node of a sparse array tree
  116. *
  117. * returns:
  118. * int the smallest index in the sparse array tree
  119. *
  120. * (Hint: consider the property of binary search tree)
  121. */
  122. int SparseArray_getMin ( SparseNode * array )
  123. {
  124. SparseNode *temp = array;
  125. while(temp->left != NULL) // iterate to lowest index
  126. {
  127. temp = temp->left;
  128. }
  129. return temp->index; // return lowest index
  130. }
  131. /* Retrieve the largest index in the sparse array tree.
  132. *
  133. * Arguments:
  134. * *array the root node of a sparse array tree
  135. *
  136. * returns:
  137. * int the largest index in the sparse array tree
  138. *
  139. * (Hint: consider the property of binary search tree)
  140. */
  141. int SparseArray_getMax ( SparseNode * array )
  142. {
  143. SparseNode *temp = array;
  144. while(temp->right != NULL) // iterate to highest index
  145. {
  146. temp = temp->right;
  147. }
  148. return temp->index; // return highest index
  149. }
  150. /* Retrieve the node associated with a specific index in a sparse
  151. * array tree.
  152. *
  153. * Arguments:
  154. * *array the root node of a sparse array tree
  155. * index the index of the node you want to search
  156. *
  157. * returns:
  158. * SparseNode* the node with the index that you searched from the tree.
  159. * If no node found, NULL should be returned.
  160. *
  161. * Hint: If the given index is smaller than the current
  162. * node, search left ; if it is larger, search right.
  163. */
  164. SparseNode * SparseArray_getNode(SparseNode * array, int index )
  165. {
  166. SparseNode *temp = array; // do not modify function parameter
  167. while(temp != NULL) // ensure pointer does not go out of tree
  168. {
  169. if(temp->index == index)
  170. {
  171. return temp; // return node if index matches key
  172. }
  173. if(temp->index > index) // move left if greater than key
  174. temp = temp->left;
  175. else
  176. temp = temp->right; // else move right
  177. }
  178. return NULL; // return NULL if index is not found
  179. }
  180. /* Remove a value associated with a particular index from the sparse
  181. * array. It returns the new
  182. * sparse array tree ( binary tree root ).
  183. *
  184. * Arguments:
  185. * *array the root node of a sparse array tree
  186. * index the index of the node you want to remove
  187. *
  188. * returns:
  189. * SparseNode* the root node of the sparse array tree that you just modified
  190. *
  191. *
  192. * HINT : First, you need to find that node. Then, you will need to isolate
  193. * several different cases here :
  194. * - If the array is empty ( NULL ), return NULL
  195. * - Go left or right if the current node index is different.
  196. * - If both subtrees are empty, you can just remove the node.
  197. * - If one subtree is empty, you can just remove the current and
  198. * replace it with the non - empty child.
  199. * - If both children exist, you must find the immediate successor of
  200. * the current node ( leftmost of right branch ), swap its values with
  201. * the current node ( BOTH index and value ), and then delete the
  202. * index in the right subtree.
  203. */
  204. SparseNode * SparseArray_remove ( SparseNode * array, int index )
  205. {
  206. if (array == NULL)
  207. return NULL; // return NULL on NULL function pass
  208. if (index < array->index) // recurse through array
  209. {
  210. array->left = SparseArray_remove(array->left, index);
  211. return array;
  212. }
  213. if (index > array->index)
  214. {
  215. array->right = SparseArray_remove(array->right, index);
  216. return array;
  217. }
  218. if (array->left == NULL && array->right == NULL)
  219. {
  220. free (array); // if parent has no children free parent
  221. return NULL;
  222. }
  223. if (array->left == NULL) // if parent has one child, free parent
  224. {
  225. SparseNode *right1 = array->right;
  226. free (array);
  227. return right1;
  228. }
  229. if (array->right == NULL)
  230. {
  231. SparseNode *left1 = array->left;
  232. free (array);
  233. return left1;
  234. }
  235. // if parent has two children
  236. SparseNode *successor = array->right; // create pointer to successor
  237. while (successor->left != NULL)
  238. {
  239. successor = successor->left; // find leftmost child of successor
  240. }
  241. int temp_value = array->value; // swap values
  242. array->index = successor->index;
  243. array->value = successor->value;
  244. successor->index = index;
  245. successor->value = temp_value;
  246. array->right = SparseArray_remove(array->right, index);
  247. return array; // return unmodified array
  248. }
  249. /* The function makes a copy of the input sparse array tree
  250. * and it returns a new copy.
  251. *
  252. * Arguments:
  253. * *array the root node of a sparse array tree
  254. *
  255. * returns:
  256. * SparseNode* the root node of the new sparse array tree that you just
  257. * copied from the input sparse array tree.
  258. *
  259. */
  260. SparseNode * SparseArray_copy(SparseNode * array)
  261. {
  262. SparseNode *temp = NULL;
  263. if(array) // recurse through array (deep copy)
  264. {
  265. temp = malloc(sizeof(SparseNode));
  266. temp->index = array->index;
  267. temp->value = array->value;
  268. temp->left = SparseArray_copy(array->left);
  269. temp->right = SparseArray_copy(array->right);
  270. }
  271. return temp; // return new array
  272. }
  273. /* Merge array_1 and array_2, and return the result array.
  274. * This function WILL NOT CHANGE the contents in array_1 and array_2.
  275. *
  276. * Arguments:
  277. * *array_1 the root node of the first sparse array tree
  278. * *array_2 the root node of the second sparse array tree
  279. *
  280. * returns:
  281. * SparseNode* the root node of the new sparse array tree that you just
  282. * merged from the two input sparse array tree
  283. *
  284. * When merging two sparse array tree:
  285. * 1. The contents in array_1 and array_2 should not be changed. You should make
  286. * a copy of array_1, and do merging in this copy.
  287. * 2. array_2 will be merged to array_1. This means you need to read nodes in
  288. * array_2 and insert them into array_1.
  289. * 3. You need to use POST-ORDER to traverse the array_2 tree.
  290. * 4. Values of two nodes need to be added only when the indices are the same.
  291. * 5. A node with value of 0 should be removed.
  292. * 6. if array_2 has nodes with index different than any nodes in array_1, you
  293. * should insert those nodes into array_1.
  294. *
  295. * Hint: you may write new functions
  296. */
  297. // helper function to remove node if its value is zero upon merger
  298. // (copy of SparseArray_insert with modifications if index == array->index)
  299. SparseNode * mergeHelp ( SparseNode * array, int index, int value )
  300. {
  301. if(index < 0 || value == 0)
  302. return array;
  303. if(array == NULL)
  304. return SparseNode_create(index, value);
  305. if(index < array->index)
  306. array->left = mergeHelp(array->left, index, value);
  307. else
  308. if(index > array->index)
  309. array->right = mergeHelp(array->right, index, value);
  310. else
  311. { // if index == array->index
  312. array->value = array->value + value; // update value
  313. if(array->value == 0) // remove node if value == 0
  314. array = SparseArray_remove(array, index);
  315. }
  316. return array;
  317. }
  318. SparseNode * SparseArray_merge(SparseNode * array_1, SparseNode * array_2)
  319. {
  320. if(array_1 == NULL && array_2 == NULL) // exit if nothing to do
  321. return NULL;
  322. if(array_1 == NULL) // nothing to merge, non-NULL array
  323. return SparseArray_copy(array_2);
  324. if(array_2 == NULL)
  325. return SparseArray_copy(array_1);
  326. SparseNode *temp;
  327. temp = SparseArray_copy(array_1);
  328. SparseNode *temp1 = NULL; // pointer to array_2 node at index i
  329. int i = SparseArray_getMin(array_2); // cycle through array_2
  330. for(i = SparseArray_getMin(array_2); i <= SparseArray_getMax(array_2); i++)
  331. {
  332. temp1 = SparseArray_getNode(array_2, i);
  333. if(temp1 != NULL)
  334. { // merge
  335. temp = mergeHelp(temp, temp1->index, temp1->value);
  336. }
  337. }
  338. return temp; // return merged array
  339. }