// // Created by william on 1/16/24. // #include #include #include #include #include "linked_list.h" LinkedList linked_list_init(bool circular) { LinkedList list; list.circular = circular; list.size = 0; list.head = NULL; list.end = NULL; list.current = NULL; return list; } void linked_list_add(LinkedList *list, void *data) { assert(list != NULL); LinkedListNode *node = malloc(sizeof(LinkedListNode)); if (node == NULL) { perror("Failed to allocate memory for linked list node"); exit(EXIT_FAILURE); } node->data = data; node->previous = list->end; if (list->head == NULL) { list->head = node; list->current = node; } if (list->end != NULL) { list->end->next = node; } if (list->circular) { node->next = list->head; } else { node->next = NULL; } list->end = node; list->size++; } LinkedListNode *linked_list_next(LinkedList *list) { assert(list != NULL); if (list->head == NULL) { return NULL; } LinkedListNode *next = list->current->next; list->current = next; return next; } void linked_list_cursor_reset(LinkedList *list) { assert(list != NULL); list->current = list->head; } LinkedListNode *linked_list_get_if(LinkedList *list, bool(*predicate)(void *, void *), void *userdata) { assert(list != NULL); assert(predicate != NULL); LinkedListNode *node = list->head; while (node != NULL) { if (predicate(node->data, userdata)) { return node; } node = node->next; } return NULL; } LinkedListNode *linked_list_get_near(LinkedList *list, int(*compute_distance)(void *, void *), void *userdata) { assert(list != NULL); assert(compute_distance != NULL); LinkedListNode *near_node = list->head; // int current_distance = compute_distance(near_node->data, userdata); // if (current_distance == 0) { // return near_node; // } int current_distance = 0x7fffffff; while (near_node->next != NULL && current_distance != 0) { int next_distance = compute_distance(near_node->next->data, userdata); if (next_distance > current_distance) { break; } near_node = near_node->next; current_distance = next_distance; } // After the loop, we have found the nearest node in the list, assuming there is only one point of convergence return near_node; } void linked_list_uninit(LinkedList *list) { assert(list != NULL); LinkedListNode *node = list->head; while (node != NULL) { LinkedListNode *current_node = node; node = node->next; free(current_node->data); free(current_node); if (node == list->head) { // The list may be circular, we don't want an infinite free loop break; } } }