Advertisement
Guest User

Untitled

a guest
Jul 25th, 2014
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.67 KB | None | 0 0
  1. /**
  2. * CS 2110 - Summer 2014 - Homework #10
  3. * Edited by: Brandon Whitehead, Andrew Wilder
  4. *
  5. * list.c: Complete the functions!
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include "list.h"
  11. /* The node struct. Has a prev pointer, next pointer, and data. */
  12. /* DO NOT DEFINE ANYTHING OTHER THAN WHAT'S GIVEN OR YOU WILL GET A ZERO*/
  13. /* Design consideration only this file should know about nodes */
  14. /* Only this file should be manipulating nodes */
  15. /* DO NOT TOUCH THIS DECLARATION DO NOT PUT IT IN OTHER FILES */
  16. typedef struct lnode
  17. {
  18. struct lnode* prev; /* Pointer to previous node */
  19. struct lnode* next; /* Pointer to next node */
  20. void* data; /* User data */
  21. } node;
  22.  
  23.  
  24. /* Do not create any global variables here. Your linked list library should obviously work for multiple linked lists */
  25. // This function is declared as static since you should only be calling this inside this file.
  26. static node* create_node(void* data);
  27.  
  28. /** create_node
  29. *
  30. * Helper function that creates a node by allocating memory for it on the heap.
  31. * Be sure to set its pointers to NULL.
  32. *
  33. * @param data a void pointer to data the user wants to store in the list
  34. * @return a node
  35. */
  36. static node* create_node(void* data)
  37. {
  38. node *n = (node*)malloc(sizeof(node));
  39. n->prev = NULL;
  40. n->next = NULL;
  41. n->data = data;
  42. return n;
  43. }
  44.  
  45. /** create_list
  46. *
  47. * Creates a list by allocating memory for it on the heap.
  48. * Be sure to initialize size to zero and head/tail to NULL.
  49. *
  50. * @return an empty linked list
  51. */
  52. list* create_list(void)
  53. {
  54. list *l = (list*)malloc(sizeof(list));
  55. l->head = NULL;
  56. l->tail = NULL;
  57. l->size = 0;
  58. return l;
  59. }
  60.  
  61. /** push_front
  62. *
  63. * Adds the data to the front of the linked list
  64. *
  65. * @param llist a pointer to the list.
  66. * @param data pointer to data the user wants to store in the list.
  67. */
  68. void push_front(list* llist, void* data)
  69. {
  70. node *newNode = create_node(data);
  71. if(llist->size == 0)
  72. {
  73. llist->head = newNode;
  74. llist->tail = newNode;
  75. llist->size = 1;
  76. }
  77. else
  78. {
  79. newNode->next = llist->head;
  80. ((llist->head)->prev) = newNode;
  81. llist->head = newNode;
  82. llist->size = (llist->size) + 1;
  83. }
  84. }
  85.  
  86. /** push_back
  87. *
  88. * Adds the data to the back/end of the linked list
  89. *
  90. * @param llist a pointer to the list.
  91. * @param data pointer to data the user wants to store in the list.
  92. */
  93. void push_back(list* llist, void* data)
  94. {
  95.  
  96. node *newNode = create_node(data);
  97.  
  98. if(llist->size == 0)
  99. {
  100.  
  101. llist->head = newNode;
  102. llist->tail = newNode;
  103. llist->size = 1;
  104. }
  105. else
  106. {
  107. llist->tail->next = newNode;
  108. newNode->prev = llist->tail;
  109. llist->tail = newNode;
  110. llist->size = llist->size + 1;
  111. }
  112. }
  113.  
  114. /** front
  115. *
  116. * Gets the data at the front of the linked list
  117. * If the list is empty return NULL.
  118. *
  119. * @param llist a pointer to the list
  120. * @return The data at the first node in the linked list or NULL.
  121. */
  122. void* front(list* llist)
  123. {
  124. if(llist == NULL)
  125. return NULL;
  126. if(llist->head == NULL)
  127. return NULL;
  128. return llist->head->data;
  129. }
  130.  
  131. /** back
  132. *
  133. * Gets the data at the "end" of the linked list
  134. * If the list is empty return NULL.
  135. *
  136. * @param llist a pointer to the list
  137. * @return The data at the last node in the linked list or NULL.
  138. */
  139. void* back(list* llist)
  140. {
  141. if(llist == NULL)
  142. return NULL;
  143. if(llist->head == NULL)
  144. return NULL;
  145. return llist->tail->data;
  146. }
  147.  
  148. /** remove_front
  149. *
  150. * Removes the node at the front of the linked list
  151. *
  152. * @warning Note the data the node is pointing to is also freed. If you have any pointers to this node's data it will be freed!
  153. *
  154. * @param llist a pointer to the list.
  155. * @param free_func pointer to a function that is responsible for freeing the node's data.
  156. * @return -1 if the remove failed (which is only there are no elements) 0 if the remove succeeded.
  157. */
  158. int remove_front(list* llist, list_op free_func)
  159. {
  160. if(llist == NULL)
  161. return -1;
  162. if(llist->size == 0)
  163. return -1;
  164. else if(llist ->size == 1)
  165. {
  166. free_func(llist->head->data);
  167. free(llist->head);
  168. llist->head = NULL;
  169. llist->tail = NULL;
  170. }
  171. else
  172. {
  173. node *newHead = llist->head->next;
  174. newHead->prev = NULL;
  175. llist->head->next = NULL;
  176. free_func(llist->head->data);
  177. free(llist->head);
  178. llist->head = newHead;
  179. }
  180. llist->size = llist->size -1;
  181. return 0;
  182. }
  183.  
  184. /** remove_back
  185. *
  186. * Removes the node at the back of the linked list
  187. *
  188. * @warning Note the data the node is pointing to is also freed. If you have any pointers to this node's data it will be freed!
  189. *
  190. * @param llist a pointer to the list.
  191. * @param free_func pointer to a function that is responsible for freeing the node's data.
  192. * @return -1 if the remove failed 0 if the remove succeeded.
  193. */
  194. int remove_back(list* llist, list_op free_func)
  195. {
  196. if(llist == NULL)
  197. return -1;
  198. if(llist->size == 0)
  199. return -1;
  200. else if(llist ->size == 1)
  201. {
  202. free_func(llist->head->data);
  203. free(llist->head);
  204. llist->head = NULL;
  205. llist->tail = NULL;
  206. }
  207. else
  208. {
  209. node *newTail = llist->tail->prev;
  210. newTail->next = NULL;
  211. llist->tail->prev = NULL;
  212. free_func(llist->tail->data);
  213. free(llist->tail);
  214. llist->tail = newTail;
  215. }
  216. llist->size = llist->size -1;
  217. return 0;
  218. }
  219.  
  220. /** copy_list
  221. *
  222. * Create a new list structure, new nodes, and new copies of the data by using
  223. * the copy function. Its implementation for any test structure must copy
  224. * EVERYTHING!
  225. *
  226. * @param llist A pointer to the linked list to make a copy of
  227. * @param copy_func A function pointer to a function that makes a copy of the
  228. * data that's being used in this linked list, allocating space for
  229. * every part of that data on the heap. This is some function you must
  230. * write yourself for testing, tailored specifically to whatever context
  231. * you're using the linked list for in your test.
  232. * @return The linked list created by copying the old one
  233. */
  234. list* copy_list(list* llist, list_cpy copy_func)
  235. {
  236. if(llist == NULL)
  237. return NULL;
  238. node *current = llist->head;
  239. list *llist2 = create_list();
  240. while(current != NULL)
  241. {
  242. void* data = copy_func(current->data);
  243. push_back(llist2, data);
  244. current = current->next;
  245. }
  246. return llist2;
  247. }
  248.  
  249.  
  250. /** size
  251. *
  252. * Gets the size of the linked list
  253. *
  254. * @param llist a pointer to the list
  255. * @return The size of the linked list
  256. */
  257. int size(list* llist)
  258. {
  259. if(llist == NULL)
  260. return 0;
  261. return llist->size;
  262. }
  263.  
  264. /** remove_if
  265. *
  266. * Removes all nodes whose data when passed into the predicate function returns true
  267. *
  268. * @param llist a pointer to the list
  269. * @param pred_func a pointer to a function that when it returns true it will remove the element from the list and do nothing otherwise @see list_pred.
  270. * @param free_func a pointer to a function that is responsible for freeing the node's data
  271. * @return the number of nodes that were removed.
  272. */
  273. int remove_if(list* llist, list_pred pred_func, list_op free_func)
  274. {
  275. if(llist == NULL)
  276. return 0;
  277. node *current = llist->head;
  278. int numNodes = 0;
  279. while(current!=NULL)
  280. {
  281. int flag = pred_func(current->data);
  282. if(flag ==1)
  283. {
  284.  
  285. numNodes = numNodes + 1;
  286. if(current == llist->head)
  287. {
  288. current = current ->next;
  289. remove_front(llist, free_func);
  290. }
  291. else if(current == llist->tail)
  292. {
  293. remove_back(llist, free_func);
  294. current = NULL;
  295. }
  296. else
  297. {
  298. node *ptr = current;
  299. current = current -> prev;
  300. current->next = current->next ->next;
  301. current->next->prev = current;
  302. ptr->prev = NULL;
  303. ptr->next = NULL;
  304. free_func(ptr->data);
  305. free(ptr);
  306. current = current->next;
  307. llist->size = llist->size -1;
  308.  
  309.  
  310. }
  311. }
  312. else
  313. current = current ->next;
  314.  
  315. }
  316. return numNodes;
  317. }
  318.  
  319. /** is_empty
  320. *
  321. * Checks to see if the list is empty.
  322. *
  323. * @param llist a pointer to the list
  324. * @return 1 if the list is indeed empty 0 otherwise.
  325. */
  326. int is_empty(list* llist)
  327. {
  328. if(llist == NULL)
  329. return 1;
  330. if(llist ->size == 0)
  331. return 1;
  332. else
  333. return 0;
  334. }
  335.  
  336. /** empty_list
  337. *
  338. * Empties the list after this is called the list should be empty.
  339. *
  340. * @param llist a pointer to a linked list.
  341. * @param free_func function used to free the node's data.
  342. */
  343. void empty_list(list* llist, list_op free_func)
  344. {
  345. int size = llist->size;
  346. for(int i= 0; i<size; i++)
  347. {
  348. remove_back(llist, free_func);
  349. }
  350. }
  351.  
  352. /** traverse
  353. *
  354. * Traverses the linked list calling a function on each node's data.
  355. *
  356. * @param llist a pointer to a linked list.
  357. * @param do_func a function that does something to each node's data.
  358. */
  359. void traverse(list* llist, list_op do_func)
  360. {
  361. if(llist == NULL)
  362. return;
  363. node *current = llist->head;
  364. while(current != NULL)
  365. {
  366. do_func(current->data);
  367. current = current->next;
  368.  
  369. }
  370. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement