char *test_split() { mu_assert(List_count(list) == 4, "Wrong count before split."); List *a = List_create(); List *b = List_create(); List *tmp = List_copy(list); int rc = -1; rc = List_split(tmp, test2, a, b); mu_assert(rc == 0, "Failed to split."); mu_assert(List_count(a) == 2, "List 'a' has wrong count."); mu_assert(List_count(b) == 2, "List 'b' has wrong count."); List_destroy(a); List_destroy(b); a = List_create(); b = List_create(); tmp = List_copy(list); rc = List_split(tmp, test1, a, b); mu_assert(rc == 0, "Failed to split."); mu_assert(List_count(a) == 1, "List 'a' has wrong count."); mu_assert(List_count(b) == 3, "List 'b' has wrong count."); List_destroy(a); List_destroy(b); a = List_create(); b = List_create(); tmp = List_copy(list); rc = List_split(tmp, test3, a, b); mu_assert(rc == 0, "Failed to split."); mu_assert(List_count(a) == 3, "List 'a' has wrong count."); mu_assert(List_count(b) == 1, "List 'b' has wrong count."); List_destroy(a); List_destroy(b); a = List_create(); b = List_create(); tmp = List_copy(list); rc = List_split(tmp, test4, a, b); mu_assert(rc == 0, "Failed to split."); mu_assert(List_count(a) == 4, "List 'a' has wrong count."); mu_assert(List_count(b) == 0, "List 'b' has wrong count."); return NULL; }
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; }
char* test_split() { List* list_test = List_create(); List_push(list_test, test1); List_push(list_test, test2); List_push(list_test, test3); List_push(list_test, test4); List_push(list_test, test5); List_push(list_test, test6); ListNode* split1 = List_find(list_test, test3); ListNode* split2 = List_find(list_test, test5); mu_assert(split1->value == test3, "Ridi"); mu_assert(split2->value == test5, "Ridi"); List** splits = List_split(list_test, 2, split1, split2); mu_assert(splits[0]->first->value == list_test->first->value, "Ridi"); mu_assert(splits[0]->first->next->value == list_test->first->next->value, "Ridi"); mu_assert(splits[0]->last->value == list_test->first->next->next->value, "Ridi"); mu_assert(splits[1]->first->value == list_test->first->next->next->next->value, "Ridi"); mu_assert(splits[1]->last->value == list_test->first->next->next->next->next->value, "Ridi"); mu_assert(splits[2]->first->value == list_test->last->value, "Ridi"); return NULL; }
List *List_merge_sort( List* words , List_compare cmp){ /* find middle , split into two lists * recursively do this ,until only one left * then recursively merge two lists */ int middle; static int i = 1; List *second; if( words->count == 0 || words->count == 1 ) return words; middle = words->count / 2; second = List_split( words , middle); assert( second != NULL ); /*after this words stores the first part before middle * and second begin with middle-th node */ words = List_merge_sort(words , cmp); second = List_merge_sort(second , cmp); // printf("times: %d\n" , i++); /* List_travers( words); List_travers( second); */ List *dest = merge_two_parts( words , second , cmp); log_info("now merge"); return dest ; }
List *List_split_test(List *list) { int index; List *right; size_t oldCount; oldCount = list->count; index = 9; List_foreach_test(list, "Before split:"); right = List_split(list, index); assert(right); assert(right->count == oldCount - index); assert(list->count == index); assert(right->first->prev == NULL); assert(list->last->next == NULL); assert(list->last != right->first); assert(list != right); return right; }
/* * 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); }