| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- #include "pa07.h"
- #include <stdio.h>
- #include <stdlib.h>
- /**
- * 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;
- }
|