#include "pa07.h" #include #include /** * Prints a linked-list "head" into the output fie "out" * * NOTE: we have given the code for this function */ void List_print(FILE * out, Node * head) { while(head != NULL) { fprintf(out, "%5d: %6d\n", head -> index, head -> value); head = head -> next; } printf("\n"); } /** * Please fill in the code below */ /** * Destroys a linked list. * Arguments: * head A pointer pointing to the first element of the linked list. * * Returns: * void * * Destroys (frees memory for) the whole linked list. * You can either use recursion or a while loop. */ void List_destroy(Node * head) { Node *temp = head; while(head != NULL) { temp = temp->next; free(head); head = temp; } } /** * Create and initialize a linked list. * * Arguments: * value The "value" of the new node * index The "index" of the new node * * Returns: * Returns a newly constructed node. The node can be the head of a * linked list. * * You should allocate memory in this function. */ Node * List_create(int value, int index) { if(value == 0 || index < 0) return NULL; Node *temp; temp = malloc(sizeof(Node)); temp->value = value; temp->index = index; temp->next = NULL; return temp; } /** * Build a sparse array from the given indices and values with * specific length. * * Arguments: * value Array of values * index Array of indices * length Length of the above arrays * * Returns: * A sparse array. * * If a sparse array node has { value = 1000, index = 2 }, then that means that * the index "2" caries the value "1000". This is meant to convey an array of 1000 * "2s", but instead of creating 1000 nodes in your linked list, you only create * 1 node, and that note conceptually has 1000 "copies" of it. Hence * each node in a sparse array has a "value" in addition to its "index". * * Note that an index can never carry the value of "0", because this would not make * any sense; however, negative values are fine. A negative value may seem odd * at first blush; however, this is like substraction, and makes sense for certain * cases. * * You need to insert nodes in ascending order by index. * See the notes to "List_insert_ascend" */ void q_sort(int *arr0, int *arr1, int start, int end) // helper function for sort { if(end - start < 1) // condition to end recursion return; int pivot = start; // set initial pivot index int val0; // create temporary variable used to swap values int val1; int i = start; // incrementor variable int j = end; // decrementor variable while(i < j) // prevent i and j from over-lapping { while(arr0[i] < arr0[pivot] && i <= end) { i++; // find index of value less than pivot value } while (arr0[j] > arr0[pivot] && j >= start) { j--; // find index of value greater than pivot value } val0 = arr0[i]; // swap value at i with value at j arr0[i] = arr0[j]; arr0[j] = val0; val1 = arr1[i]; arr1[i] = arr1[j]; arr1[j] = val1; } // repeat for all values i < j, i.e. one pass q_sort(arr0, arr1, start, j-1); // repeat for sub array of smaller indices q_sort(arr0, arr1, j+1, end); // repeat for sub array of larger indices } Node * List_build(int * value, int * index, int length) { if(length < 1) return NULL; q_sort(index, value, 0, length - 1); Node *head = NULL; Node *temp = NULL; int i; for(i = length - 1; i >= 0; i--) { if(value[i] != 0) { temp = List_create(value[i], index[i]); temp->next = head; head = temp; } } return head; } /** * Inserting "value" and "index" into the correct location in the * sparse array "head" * * Arguments: * head A pointer pointing to the first element of the linked list. * value The "value" of the value * index The "value" of the index * * Returns: * A sparse array * * This function inserts the node ["value", "index"] into the sparse * array "head", and ensures that the nodes remain in ascending order * by their "index". * * Before and after the call to this function, "head" must be in * ASCENDING order by the "index" of each node. */ Node * List_insert_ascend(Node * head, int value, int index) { if(head == NULL) return NULL; Node *temp = NULL; Node *temp1 = head; while(temp1 != NULL) { if(index < temp1->index) { temp = List_create(value, index); temp->next = temp1; return temp; } if(index == temp1->index) { temp1->value = temp1->value + value; return head; } if(temp1->next == NULL) { temp = List_create(value, index); temp->next = temp1->next; temp1->next = temp; return head; } if(index > temp1->index && index < temp1->next->index) { temp = List_create(value, index); temp->next = temp1->next; temp1->next = temp; return head; } temp1 = temp1->next; } return head; } /** * This function deletes the node with the passed "index" * * Arguments: * head A pointer pointing to the first element of the sparse array. * index The index to be deleted * * Returns: * A sparse array with the node removed (the one with index) */ Node * List_delete(Node * head, int index) { if(head == NULL) return NULL; Node *temp; temp = head; Node *temp1; temp1 = head; if (temp == NULL) return temp; if (head->index == index) { if(head->next == NULL) { free(head); return NULL; } else { head->index = head->next->index; head->value = head->next->value; temp = head->next; head->next = head->next->next; free(temp); temp1 = head->next; } } while(temp1->next != NULL) { if(temp1->next->index == index) { temp = temp1->next; temp1->next = temp1->next->next; free(temp); return head; } } return head; } /** * Copy a list * * Arguments: * head A pointer pointing to the first element of the sparse array * * Returns: * A copy sparse array * * This function will copy the sparse array that is passed to it. The * copy will be made into new memory. * * This is useful, for example, when we want to merge * two linked lists together. We can make a copy of one of the linked * lists, and then merge the second into the copy. In this way the * original copy of the list is not "mutated". */ Node * List_copy(Node * head) { if(head == NULL) return NULL; Node *temp = head; Node *copy = malloc(sizeof(Node)); copy->value = temp->value; copy->index = temp->index; copy->next = NULL; Node *const head1 = copy; temp = temp->next; while (temp != NULL) { copy = copy->next = malloc(sizeof(Node)); copy->value = temp->value; copy->index = temp->index; copy->next = NULL; temp = temp->next; } return head1; } /** * Merged two linked list together * * Arguments: * head1 A pointer pointing to linked list 1 * head2 A pointer pointing to linked list 2 * * Returns: * A merged sparse array * * This function will merge two linked lists. Before merging, you * should make a copy of "head1" so that you will still have the * original array while modifying (merging) the second linked list. * * Please refer to the README file for detailed instructions on how to * merge two lists. * * This function should not modify either "head1" or "head2". You only * need to make a clone of "head1". */ Node * List_merge(Node * head1, Node * head2) { if(head1 == NULL) return List_copy(head2); if(head2 == NULL) return List_copy(head1); Node *temp; temp = List_copy(head1); Node *temp1; temp1 = head2; while(temp1 != NULL) { temp = List_insert_ascend(temp, temp1->value, temp1->index); temp1 = temp1->next; } temp1 = temp; while(temp != NULL) { if(temp->value == 0) temp = List_delete(temp, temp->index); temp = temp->next; } return temp1; }