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)); }
/** * 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; }
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); }
/* * 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); }
void cerebrod_speaker_data_metric_list_sort(void) { #if CEREBRO_DEBUG #if !WITH_CEREBROD_NO_THREADS int rv; #endif /* !WITH_CEREBROD_NO_THREADS */ #endif /* CEREBRO_DEBUG */ assert(metric_list); #if CEREBRO_DEBUG #if !WITH_CEREBROD_NO_THREADS /* Should be called with lock already set */ rv = Pthread_mutex_trylock(&metric_list_lock); if (rv != EBUSY) CEREBRO_EXIT(("mutex not locked: rv=%d", rv)); #endif /* !WITH_CEREBROD_NO_THREADS */ #endif /* CEREBRO_DEBUG */ List_sort(metric_list, _next_call_time_cmp); }
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; }
int main(int argc, char *argv[]){ printf("Starting tests...\n"); struct nodeStruct *head = NULL; // Starting count: assert(List_countNodes(head) == 0); // Create 1 node: struct nodeStruct* firstNode = List_createNode(0); List_insertHead(&head, firstNode); assert(List_countNodes(head) == 1); assert(List_findNode(head, 0) == firstNode); assert(List_findNode(head, 1) == NULL); // Insert tail: struct nodeStruct* lastNode = List_createNode(-5); List_insertTail(&head, lastNode); struct nodeStruct* lastNode2 = List_createNode(2); List_insertTail(&head, lastNode2); struct nodeStruct* lastNode3 = List_createNode(3); List_insertTail(&head, lastNode3); struct nodeStruct* lastNode4 = List_createNode(8); List_insertTail(&head, lastNode4); assert(List_countNodes(head) == 5); assert(List_findNode(head, 0) == firstNode); assert(List_findNode(head, -5) == lastNode); assert(List_findNode(head, 1) == NULL); // Verify list: struct nodeStruct *current = head; assert(current->item == 0); assert(current->next != NULL); current = current->next; assert(current->item == -5); assert(current->next != NULL); // Sort and verify: List_sort(&head); current = head; assert(current->item == -5); assert(current->next != NULL); current = current->next; assert(current->item == 0); assert(current->next != NULL); // Delete assert(List_countNodes(head) == 5); List_deleteNode(&head, firstNode); assert(List_countNodes(head) == 4); assert(List_findNode(head, 0) == NULL); assert(List_findNode(head, 1) == NULL); current = head; assert(current->item == -5); assert(current->next->item == 2); printf("\nExecution finished.\n"); return 0; return 0; }
/* * Under almost any circumstance, don't return a -1 error, cerebro can * go on without loading monitor modules. The listener_data_init_lock * should already be set. */ int cerebrod_event_modules_setup(void) { int i, event_module_count, event_index_len, event_index_count = 0; struct cerebrod_event_module_list *el = NULL; #if CEREBRO_DEBUG int rv; #endif /* CEREBRO_DEBUG */ assert(listener_data); #if CEREBRO_DEBUG /* Should be called with lock already set */ rv = Pthread_mutex_trylock(&listener_data_init_lock); if (rv != EBUSY) CEREBROD_EXIT(("mutex not locked: rv=%d", rv)); #endif /* CEREBRO_DEBUG */ if (!conf.event_server) return 0; if (!(event_handle = event_modules_load())) { CEREBROD_DBG(("event_modules_load")); goto cleanup; } if ((event_module_count = event_modules_count(event_handle)) < 0) { CEREBROD_DBG(("event_modules_count")); goto cleanup; } if (!event_module_count) { if (conf.debug && conf.event_server_debug) { Pthread_mutex_lock(&debug_output_mutex); fprintf(stderr, "**************************************\n"); fprintf(stderr, "* No Event Modules Found\n"); fprintf(stderr, "**************************************\n"); Pthread_mutex_unlock(&debug_output_mutex); } goto cleanup; } /* Each event module may want multiple metrics and/or offer multiple * event names. We'll assume there will never be more than 2 per * event module, and that will be enough to avoid all hash * collisions. */ event_index_len = event_module_count * 2; event_index = Hash_create(event_index_len, (hash_key_f)hash_key_string, (hash_cmp_f)strcmp, (hash_del_f)_cerebrod_event_module_list_destroy); event_names = List_create((ListDelF)_Free); event_module_timeouts = List_create((ListDelF)_cerebrod_event_module_timeout_data_destroy); event_module_timeout_index = Hash_create(event_module_count, (hash_key_f)hash_key_string, (hash_cmp_f)strcmp, (hash_del_f)list_destroy); for (i = 0; i < event_module_count; i++) { struct cerebrod_event_module *event_module; char *module_name, *module_metric_names, *module_event_names; char *metricPtr, *metricbuf; char *eventnamePtr, *eventbuf; int timeout; module_name = event_module_name(event_handle, i); if (conf.event_module_exclude_len) { int found_exclude = 0; int j; for (j = 0; j < conf.event_module_exclude_len; j++) { if (!strcasecmp(conf.event_module_exclude[j], module_name)) { found_exclude++; break; } } if (found_exclude) { if (conf.debug && conf.event_server_debug) { Pthread_mutex_lock(&debug_output_mutex); fprintf(stderr, "**************************************\n"); fprintf(stderr, "* Skip Event Module: %s\n", module_name); fprintf(stderr, "**************************************\n"); Pthread_mutex_unlock(&debug_output_mutex); } CEREBROD_ERR(("Dropping event module: %s", module_name)); continue; } } if (conf.debug && conf.event_server_debug) { Pthread_mutex_lock(&debug_output_mutex); fprintf(stderr, "**************************************\n"); fprintf(stderr, "* Setup Event Module: %s\n", module_name); fprintf(stderr, "**************************************\n"); Pthread_mutex_unlock(&debug_output_mutex); } if (event_module_setup(event_handle, i) < 0) { CEREBROD_DBG(("event_module_setup failed: %s", module_name)); continue; } if (!(module_metric_names = event_module_metric_names(event_handle, i)) < 0) { CEREBROD_DBG(("event_module_metric_names failed: %s", module_name)); event_module_cleanup(event_handle, i); continue; } if (!(module_event_names = event_module_event_names(event_handle, i)) < 0) { CEREBROD_DBG(("event_module_event_names failed: %s", module_name)); event_module_cleanup(event_handle, i); continue; } if ((timeout = event_module_timeout_length(event_handle, i)) < 0) { CEREBROD_DBG(("event_module_timeout_length failed: %s", module_name)); event_module_cleanup(event_handle, i); continue; } event_module = Malloc(sizeof(struct cerebrod_event_module_info)); event_module->metric_names = Strdup(module_metric_names); event_module->event_names = Strdup(module_event_names); event_module->index = i; Pthread_mutex_init(&(event_module->event_lock), NULL); /* The monitoring module may support multiple metrics */ metricPtr = strtok_r(event_module->metric_names, ",", &metricbuf); while (metricPtr) { if (!(el = Hash_find(event_index, metricPtr))) { el = (struct cerebrod_event_module_list *)Malloc(sizeof(struct cerebrod_event_module_list)); el->event_list = List_create((ListDelF)_cerebrod_event_module_info_destroy); Pthread_mutex_init(&(el->event_list_lock), NULL); List_append(el->event_list, event_module); Hash_insert(event_index, metricPtr, el); event_index_count++; } else List_append(el->event_list, event_module); metricPtr = strtok_r(NULL, ",", &metricbuf); } /* The monitoring module may support multiple event names */ eventnamePtr = strtok_r(event_module->event_names, ",", &eventbuf); while (eventnamePtr) { if (!list_find_first(event_names, (ListFindF)_cerebrod_name_strcmp, eventnamePtr)) { List_append(event_names, eventnamePtr); if (conf.debug && conf.event_server_debug) { Pthread_mutex_lock(&debug_output_mutex); fprintf(stderr, "**************************************\n"); fprintf(stderr, "* Event Name: %s\n", eventnamePtr); fprintf(stderr, "**************************************\n"); Pthread_mutex_unlock(&debug_output_mutex); } } eventnamePtr = strtok_r(NULL, ",", &eventbuf); } if (timeout) { struct cerebrod_event_module_timeout_data *mtd; List modules_list; if (!(mtd = List_find_first(event_module_timeouts, _event_module_timeout_data_find_callback, &timeout))) { char strbuf[64]; mtd = (struct cerebrod_event_module_timeout_data *)Malloc(sizeof(struct cerebrod_event_module_timeout_data)); mtd->timeout = timeout; snprintf(strbuf, 64, "%d", timeout); mtd->timeout_str = Strdup(strbuf); List_append(event_module_timeouts, mtd); if (timeout < event_module_timeout_min) event_module_timeout_min = timeout; } if (!(modules_list = Hash_find(event_module_timeout_index, mtd->timeout_str))) { modules_list = List_create((ListDelF)NULL); List_append(modules_list, event_module); Hash_insert(event_module_timeout_index, mtd->timeout_str, modules_list); } else List_append(modules_list, event_module); } } List_sort(event_module_timeouts, _event_module_timeout_data_compare); if (!event_index_count) goto cleanup; if (_setup_event_node_timeout_data() < 0) goto cleanup; /* * Since the cerebrod listener is started before any of the event * threads (node_timeout, queue_monitor, server), this must be * created in here (which is called by the listener) to avoid a * possible race of modules creating events before the event_queue * is created. */ event_queue = List_create((ListDelF)cerebrod_event_to_send_destroy); return 1; cleanup: if (event_handle) { event_modules_unload(event_handle); event_handle = NULL; } if (event_index) { Hash_destroy(event_index); event_index = NULL; } if (event_names) { List_destroy(event_names); event_names = NULL; } return 0; }