List * List_sort(List * list, int (*compar)(const char *, const char*)) { int length = List_length(list); int halfLength = length / 2; if (length <= 1) { return (list); } List * lhs = list; List * lhsTail = list; while (--halfLength > 0) { lhsTail = lhsTail -> next; } List * rhs = lhsTail -> next; lhsTail -> next = NULL; lhs = List_sort(lhs, compar); rhs = List_sort(rhs, compar); return (List_merge(lhs, rhs, compar)); }
List *List_merge_sort(List *list, List_compare cmp){ if(List_count(list)<=1){ return list; } List *left=List_create(); List *right=List_create(); int middle=List_count(list)/2; LIST_FOREACH(list, first, next, cur){ if(middle>0){ List_push(left, cur->value); } else { List_push(right, cur->value); } middle--; } List *sort_left=List_merge_sort(left, cmp); List *sort_right=List_merge_sort(right, cmp); if(sort_left !=left) List_destroy(left); if(sort_right !=right)List_destroy(right); return List_merge(sort_left, sort_right, cmp); }
List *List_merge_sort(List *list, List_compare cmp) { assert(list != NULL && "list can't be NULL"); assert(cmp != NULL && "cmp can't be NULL"); if(List_count(list) <= SUB_LIST_MIN_SIZE) { int rc = List_bubble_sort(list, cmp); assert(rc == 0 && "Bubble sort failed."); return list; } List *left = List_create(); List *right = List_create(); int middle = List_count(list) / 2; List_split(list, left, middle, right, List_count(list) - middle); List *sort_left = List_merge_sort(left, cmp); List *sort_right = List_merge_sort(right, cmp); if(sort_left != left) List_clear_destroy(left); if(sort_right != right) List_clear_destroy(right); List *merged_list = List_merge(sort_left, sort_right, cmp); List_clear_destroy(sort_left); List_clear_destroy(sort_right); return merged_list; }
List *List_merge_sort(List *list, List_compare cmp) { // 未初始化的List,视为不能排序 if(list == NULL) return NULL; // 空List和只有一个节点的List视为已经排序 if(List_count(list) < 2) return list; int i = 1; ListNode *cur = list->first; List *left = List_create(); List *right= List_create(); int middle = List_count(list) / 2; // 拆成两个List,分别排序 for(i = 1; i < middle; i++) { List_push(left, cur->value); cur=cur->next; } for(i = 1; i <= List_count(list) - middle; i++) { List_push(right, cur->value); cur=cur->next; } List *sort_left = List_merge_sort(left, cmp); List *sort_right = List_merge_sort(right, cmp); if(sort_left != left) List_destroy(left); if(sort_right != right) List_destroy(right); // merge return List_merge(sort_left, sort_right, cmp); }
int main(int argc, char ** argv) { if (argc != 3) { printf("Usage: ./pa05 <input file 1> <input file 2>\n"); return EXIT_FAILURE; } // Input file processed, ready to build the sparse-array Node * array1 = NULL, * array2 = NULL; int okay = TRUE; okay = okay && readSparseArrayFile(argv[1], &array1); okay = okay && readSparseArrayFile(argv[2], &array2); if(okay) { FILE * out = stdout; // This is where we output results printf("*******************************\n"); printf("Array 1:\n"); printf("*******************************\n"); List_print(out, array1); printf("\n*******************************\n"); printf("Array 2:\n"); printf("*******************************\n"); List_print(out, array2); printf("\n*******************************\n"); printf("Copy of Array 1:\n"); printf("*******************************\n"); Node * clone_array = List_copy(array1); List_print(out, clone_array); printf("\n*******************************\n"); printf("Merged array:\n"); printf("*******************************\n"); Node * array_new = List_merge(array1, array2); List_print(out, array_new); printf("\n\nArray destroy sequence 1\n\n"); // List_destroy(array_new); // List_destroy(clone_array); } printf("\n\nArray destroy sequence 2\n\n"); fflush(stdout); // List_destroy(array1); // List_destroy(array2); return EXIT_SUCCESS; }
/** * Sorts the list's elements using the merge-sort algorithm. * Merge-sort is a recursive algorithm. See the README for hints. * * The brief instructions are as follows: * * (1) Base case: * Lists of length 0 or 1 are already (defacto) sorted. In this case, return * 'list'. * * (2) Recursive case: * (2.a) Split the linked-list into two approx. equal sized lists. * (2.b) Call List_sort(...) on each of these smaller lists. * (2.c) Call List_merge(...) to merge the now sorted smaller lists into a * single larger sorted list, which you return. * * Well-written code should be 20-30 lines long, including comments and spacing. * If your code is longer than this, then you may save time by rethinking your * approach. */ List * List_sort(List * list, int (*compar)(const char *, const char*)){ int len = List_length(list); //base case------------------------------------------------------- if (len < 2) { return list; } //recursive case--------------------------------------------------- //split linked list into two approx. equal sized lists int i; int mid; List * left = NULL; List * right = NULL; List ** l_current = &left; List ** r_current = &right; i = 0; mid = len/2; while (list){ //add to left if (i < mid) { *l_current = list; //move the entire list over to left list = list -> next; //make list's head the next node of list l_current = &(*l_current) -> next; //move to the next node of left *l_current = NULL; //ensure that it points to NULL } //add to right else{ *r_current = list; list = list -> next; r_current = &(*r_current) -> next; } i++; } //call list sort on each of these smaller lists left = List_sort(left, strcmp); right = List_sort(right, strcmp); //call list merge on these two sorted lists List * sorted = NULL; sorted = List_merge(left, right, strcmp); return sorted; }
/* This is a helper method used for the mergesort algorithm*/ struct nodeStruct* List_merge(struct nodeStruct* leftHead, struct nodeStruct* rightHead) { struct nodeStruct* result =NULL; if(leftHead==NULL)//base case of recursion return rightHead; if(rightHead==NULL)//base case of recursion return leftHead; if((*leftHead).item<=(*rightHead).item)//if element in left list smaller or equal than right, merge into result { result=leftHead; (*result).next=List_merge((*leftHead).next,rightHead);//calls method merge recursively } else { result=rightHead; (*result).next=List_merge(leftHead,(*rightHead).next); } return result; }
int main (int argc, char * argv[]) { printf("make a node and print it"); Node * test = List_create(5,1); List_print(stdout, test); printf("destroying it"); List_destroy(test); List_print(stdout, test); printf("linkingit again"); Node * newnode =NULL; Node * newnode2 = NULL; int values[4] = {2,3,1,2}; int indexs[4] = {1,4,2,3}; // int i; int length = 4; printf("this is newnode"); newnode = List_build(values, indexs, length); //printf("this is the newnode"); //List_print(stdout, newnode); //printf("address:%p", newnode->next); //printf("address:%p", newnode->next->next); newnode2 = List_copy(newnode); printf("copy of new node"); List_print(stdout, newnode2); //List_print(stdout, newnode); Node * merged = NULL; merged = List_merge(newnode, newnode2); List_print(stdout, merged); // printf("copy linked list"); /* while (newnode!= NULL) { List_print(stdout, newnode); printf("this is the address : %p", newnode->next); } */ //newnode = List_insert_ascend(newnode -> next,3,4); //List_print(stdout, newnode); //printf("this is the address : %p", newnode->next); //List_print(stdout, newnode -> next); return 0; }
List * List_sort(List * list, int (*compar)(const char *, const char*)) { int length=List_length(list); //Base Case if(length<=1) return list; //Recursive Case int half_length=length/2; List *lhs=list; List *lhs_tail=list; while(--half_length>0) lhs_tail=lhs_tail->next; List *rhs=lhs_tail->next; lhs_tail->next=NULL; //Merge lhs=List_sort(lhs,compar); rhs=List_sort(rhs,compar); return List_merge(lhs,rhs,compar); }
List *List_merge_sort(List *list, List_compare cmp) { if(List_count(list) <= 1) { return list; } List *left = List_create(); List *right = List_create(); int index = 0; LIST_FOREACH(list, first, next, cur) { if(index%2 == 1) { List_push(left, cur->value); } else { List_push(right, cur->value); } ++index; } left = List_merge_sort(left, cmp); right = List_merge_sort(right, cmp); return List_merge(left, right, cmp); }
/* * Sort the list in ascending order based on the item field. * Any sorting algorithm is fine. */ void List_sort (struct nodeStruct **headRef) { /* Complete the body of the function */ struct nodeStruct* leftList=NULL; struct nodeStruct* rightList=NULL; struct nodeStruct* head=*headRef; if(head==NULL || (*head).next==NULL)//exits the method if list has less than 2 elements { return; } List_split(head,&leftList,&rightList);//splitting list //recursively calls the sort methods List_sort(&leftList); List_sort(&rightList); //result stored in *headRef *headRef=List_merge(leftList,rightList); }
int main(int argc, char * * argv) { printf("---------------------Testing Answer08-----------------------\n"); // Create two linked lists List * head1 = NULL; head1 = List_Insert(head1, "a"); head1 = List_Insert(head1, "c"); head1 = List_Insert(head1, "e"); List_print(head1); List * head2 = NULL; head2 = List_Insert(head2, "b"); head2 = List_Insert(head2, "d"); head2 = List_Insert(head2, "f"); head2 = List_Insert(head2, "g"); List_print(head2); List * head3 = NULL; head3 = List_Insert(head3, "x"); head3 = List_Insert(head3, "i"); head3 = List_Insert(head3, "f"); head3 = List_Insert(head3, "r"); List_print(head3); printf("List length of 1 is: %d\n", List_length(head1)); printf("List length of 2 is: %d\n", List_length(head2)); printf("---------------------Testing Merge-----------------------\n"); List * newlist; newlist = List_merge(head1, head2, strcmp); List_print(newlist); printf("---------------------Testing Merge-----------------------\n"); List * sorted; sorted = List_sort(head3, strcmp); List_print(sorted); return EXIT_SUCCESS; }
static int test_merge(List * lhs, List * rhs, int (*compar)(const char *, const char *)) { int success = TRUE; // until proven otherwise // First make sure our lists are sorted... lhs = List_sort_sol(lhs, compar); rhs = List_sort_sol(rhs, compar); // What are we testing? printf("Testing List_merge(lhs, rhs, compar), where:\n\n"); printf("+ compar is: "); print_compar(compar); printf("\n"); printf("+ lhs is: "); List_print(lhs); printf("\n"); printf("+ rhs is: "); List_print(rhs); printf("\n"); // Check that the student doesn't reallocate nodes... store lhs/rhs pointers int len = List_length_sol(lhs) + List_length_sol(rhs); List * * nodeArr = malloc(len * sizeof(List *)); int ind = 0; List * node = NULL; node = lhs; while(node != NULL) { nodeArr[ind++] = node; node = node->next; } node = rhs; while(node != NULL) { nodeArr[ind++] = node; node = node->next; } // Clone lhs, rhs, and get the solution List * solution = List_merge_sol(List_clone(lhs), List_clone(rhs), compar); // Run the students code List * merged = List_merge(lhs, rhs, compar); printf("\nmerged is : "); List_print(merged); printf("\nsolution is: "); List_print(solution); printf("\n"); // Are we the correct length? int merged_len = List_length_sol(merged); if(merged_len != len) { printf("Error: merged solution has length %d, but it should be %d\n", merged_len, len); success = FALSE; } // Check the solution is in order, and that every Node pointer is in nodeArr List * sol_node = solution; node = merged; while(node != NULL && sol_node != NULL) { int found = FALSE; for(ind = 0; ind < len && !found; ++ind) found = (nodeArr[ind] == node); if(!found) { printf("Error: merged list contained a node with pointer %p; \n" "however, this pointer was not in either of the inputs.\n" "(i.e., 'lhs', or 'rhs'.) You must not create or destroy\n" "any nodes when writing the merge function.\n", node); success = FALSE; } if(strcmp(node->str, sol_node->str) != 0) { printf("Error: merged list not in order (!)\n"); success = FALSE; } sol_node = sol_node->next; node = node->next; } // Cleanup. free(nodeArr); List_destroy_sol(solution); List_destroy_sol(merged); return success; }