From 6dbe9416605b2819db4b29310a7356a8e747e026 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Thu, 8 Jan 2026 19:15:15 +0100 Subject: [PATCH] feat: lists (finished) --- src/utils/lists/lists.c | 306 ++++++++++++++++++++++++++++++++++++++++ src/utils/lists/lists.h | 110 +++++++++++++++ 2 files changed, 416 insertions(+) create mode 100644 src/utils/lists/lists.c create mode 100644 src/utils/lists/lists.h diff --git a/src/utils/lists/lists.c b/src/utils/lists/lists.c new file mode 100644 index 0000000..be97835 --- /dev/null +++ b/src/utils/lists/lists.c @@ -0,0 +1,306 @@ +#include "lists.h" + +#include +#include +#include + +struct list *list_prepend(struct list *list, void *value) +{ + struct list *new_elt = malloc(sizeof(struct list)); + if (new_elt == NULL) + { + return NULL; + } + new_elt->next = list; + new_elt->data = value; + + return new_elt; +} + +size_t list_length(struct list *list) +{ + size_t len = 0; + while (list != NULL) + { + len++; + list = list->next; + } + return len; +} + +void list_print(struct list *list) +{ + if (list == NULL) + { + return; + } + + while (list != NULL) + { + if (list->next != NULL) + { + printf("%p ", list->data); + } + else + { + printf("%p\n", list->data); + } + list = list->next; + } +} + +void list_destroy(struct list *list) +{ + struct list *elt = list; + struct list *next_elt; + while (elt != NULL) + { + next_elt = elt->next; + free(elt); + elt = next_elt; + } +} + +struct list *list_append(struct list *list, void *value) +{ + if (list == NULL) + { + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->data = value; + new_elt->next = NULL; + return new_elt; + } + + struct list *elt = list; + + while (elt->next != NULL) + { + elt = elt->next; + } + + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->data = value; + new_elt->next = NULL; + elt->next = new_elt; + + return list; +} + +/* + * + ******************* + * Advanced * + ******************* + * + */ + +struct list *list_insert(struct list *list, void *value, size_t index) +{ + if (list == NULL || index == 0) + { + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->data = value; + new_elt->next = list; + return new_elt; + } + + struct list *elt = list; + + for (size_t i = 0; i < index - 1; i++) + { + if (elt->next == NULL) + { + break; + } + elt = elt->next; + } + + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->data = value; + new_elt->next = elt->next; + elt->next = new_elt; + + return list; +} + +struct list *list_remove(struct list *list, size_t index) +{ + struct list *elt = list; + struct list *prev_elt; + + if (index == 0) + { + struct list *res = elt->next; + free(elt); + return res; + } + + for (size_t i = 0; i < index; i++) + { + if (elt == NULL) + { + return list; + } + prev_elt = elt; + elt = elt->next; + } + if (elt == NULL) + { + return list; + } + + prev_elt->next = elt->next; + free(elt); + + return list; +} + +int list_find(struct list *list, void *value) +{ + if (list == NULL) + { + return -1; + } + + int res = 0; + while (list->data != value) + { + list = list->next; + res++; + if (list == NULL) + { + return -1; + } + } + return res; +} + +struct list *list_concat(struct list *list, struct list *list2) +{ + if (list == NULL) + { + return list2; + } + struct list *elt = list; + while (elt->next != NULL) + { + elt = elt->next; + } + elt->next = list2; + return list; +} + +/* + * + ****************** + * Ultimate * + ****************** + * + */ + +static void swap_next(struct list *elt) +{ + void *c = elt->next->data; + elt->next->data = elt->data; + elt->data = c; +} +struct list *list_sort(struct list *list) +{ + // Bubble sort go ! + if (list == NULL) + { + return list; + } + struct list *elt = list; + int len = 0; + while (elt->next != NULL) + { + if (elt->data > elt->next->data) + { + swap_next(elt); + } + elt = elt->next; + len++; + } + + for (int i = 1; i < len; i++) + { + elt = list; + while (elt->next != NULL) + { + if (elt->data > elt->next->data) + { + swap_next(elt); + } + elt = elt->next; + } + } + + return list; +} + +// Old proto +// WARNING no malloc/free allowed (moulinette issue) +struct list *list_reverse(struct list *list) +{ + if (list == NULL) + { + return list; + } + + // Get len + struct list *elt = list; + int len = 0; + while (elt->next != NULL) + { + len++; + elt = elt->next; + } + elt = list; + + // Bring each elt to end + for (int i = 0; i < len; i++) + { + elt = list; + for (int j = 0; j < len - i; j++) + { + swap_next(elt); + elt = elt->next; + } + } + + return list; +} + +struct list *list_split(struct list *list, size_t index) +{ + struct list *elt = list; + for (size_t i = 0; i < index; i++) + { + if (elt == NULL) + { + return NULL; + } + elt = elt->next; + } + if (elt == NULL) + { + return NULL; + } + struct list *res = elt->next; + elt->next = NULL; + return res; +} + +void list_deep_destroy(struct list *l) +{ + struct list *elt = l; + struct list *next_elt; + while (elt != NULL) + { + next_elt = elt->next; + free(elt->data); + free(elt); + elt = next_elt; + } +} diff --git a/src/utils/lists/lists.h b/src/utils/lists/lists.h new file mode 100644 index 0000000..a0fedf3 --- /dev/null +++ b/src/utils/lists/lists.h @@ -0,0 +1,110 @@ +#ifndef LISTS_H +#define LISTS_H + +#include + +struct list +{ + void *data; + struct list *next; +}; + +/* +** @brief Insert a node containing `value` at the beginning of the list. +** @return `NULL` if an error occured. +*/ +struct list *list_prepend(struct list *list, void *value); + +/* +** Return the lenght of the list. +** Return `0` if the list is empty. +*/ +size_t list_length(struct list *list); + +/* +** Display the list contents on `stdout`. +** Nothing is displayed if the list is empty. +*/ +void list_print(struct list *list); + +/* +** Release the memory used by the list. +** Does nothing if `list` is `NULL`. +*/ +void list_destroy(struct list *list); + +/* +** Release the memory used by the list and its content +** Does nothing if `list` is `NULL`. +*/ +void list_deep_destroy(struct list *l); + +/* +** Append a node containing `value` at the end of the list. +** Return `NULL` if an error occured. +*/ +// START PROTO list_append +struct list *list_append(struct list *list, void *value); +// END PROTO list_append + +/* +** Insert a node containing `value` at the index `index` in the list. +** If the index is greater than the length of the list, the behaviour is the +** same as `list_append`. +** Return `NULL` if an error occured. +*/ +// START PROTO list_insert +struct list *list_insert(struct list *list, void *value, size_t index); +// END PROTO list_insert + +/* +** Remove the element at the index `index`. +** Return `NULL` if an error occured. +*/ +// START PROTO list_remove +struct list *list_remove(struct list *list, size_t index); +// END PROTO list_remove + +/* +** Return the position of the first node containing `value`. +** Return `-1` if nothing is found. +*/ +// START PROTO list_find +int list_find(struct list *list, void *value); +// END PROTO list_find + +/* +** Concatenate the list `list2` at the end of the list `list`. +** Return `list2` if `list` is `NULL`. +*/ +// START PROTO list_concat +// struct list *list_concat(struct list *list, struct list *list2); +// END PROTO list_concat + +/* +** Sort the elements of the list in ascending order. +** Return the new list. +*/ +// START PROTO list_sort +// struct list *list_sort(struct list *list); +// END PROTO list_sort + +/* +** Invert the order of the elements of the list. +** Return the new list. +*/ +// START PROTO list_reverse +// struct list *list_reverse(struct list *list); +// END PROTO list_reverse + +/* +** Split the list at index `index`. +** First part goes in `list` and contains the element at `index`. +** Second part is returned. +** Return `NULL` if `list` is `NULL` or `index` is invalid. +*/ +// START PROTO list_split +// struct list *list_split(struct list *list, size_t index); +// END PROTO list_split + +#endif /* ! LISTS_H */