diff --git a/slides/exemples/dll_solution.c b/slides/exemples/dll_solution.c new file mode 100644 index 0000000000000000000000000000000000000000..ff072956a36c05ece52211203319107cac434db5 --- /dev/null +++ b/slides/exemples/dll_solution.c @@ -0,0 +1,201 @@ +#include "dll.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static element_t *create_element(int data, element_t *prev, element_t *next) { + element_t *elem = (element_t *)malloc(sizeof(*elem)); + if (NULL == elem) { + return NULL; + } + elem->data = data; + elem->prev = prev; + elem->next = next; + return elem; +} + +void dll_init(dll *list) { + list->pos = NULL; + list->head = NULL; +} + +bool dll_is_empty(dll list) { + return (NULL == list.head && NULL == list.pos); +} + +bool dll_value(dll list, int *val) { + if (dll_is_empty(list)) { + return false; + } + *val = list.pos->data; + return true; +} + +bool dll_is_head(dll list) { + return (!dll_is_empty(list) && list.pos == list.head); +} + +bool dll_is_tail(dll list) { + return (!dll_is_empty(list) && NULL == list.pos->next); +} + +bool dll_is_present(dll list, int data) { + dll_move_to_head(&list); + int l_data = 0; + while (dll_value(list, &l_data)) { + if (data == l_data) { + return true; + } else if (dll_is_tail(list)) { + return false; + } + dll_next(&list); + } + return false; +} + +static char *robust_realloc(char *str, size_t num) { + char *new_str = (char *)realloc(str, num * sizeof(*new_str)); + if (NULL == new_str) { + free(str); + return NULL; + } + return new_str; +} + +char *dll_to_str(dll list) { + char *str = (char *)malloc(sizeof(*str)); + str[0] = 0; + if (dll_is_empty(list)) { + return str; + } + dll_move_to_head(&list); + + int data = 0; + while (dll_value(list, &data)) { + char buffer[12]; // normally largest posible string is -2e9 (11 digits + // and space and 0) + if (dll_is_tail(list)) { + sprintf(buffer, "%d", data); + str = robust_realloc(str, strlen(str) + strlen(buffer) + 1); + if (NULL == str) { + return NULL; + } + strncat(str, buffer, strlen(str) + strlen(buffer) + 1); + break; + } else { + sprintf(buffer, "%d ", data); + str = robust_realloc(str, strlen(str) + strlen(buffer) + 1); + if (NULL == str) { + return NULL; + } + strncat(str, buffer, strlen(str) + strlen(buffer) + 1); + } + dll_next(&list); + } + return str; +} + +void dll_move_to_head(dll *list) { + list->pos = list->head; +} + +void dll_next(dll *list) { + if (!dll_is_tail(*list) && !dll_is_empty(*list)) { + list->pos = list->pos->next; + } +} + +void dll_prev(dll *list) { + if (!dll_is_head(*list) && !dll_is_empty(*list)) { + list->pos = list->pos->prev; + } +} + +bool dll_insert_after(dll *list, int data) { + if (dll_is_empty(*list)) { + element_t *elem = create_element(data, NULL, NULL); + if (NULL == elem) { + return false; + } + list->head = list->pos = elem; + } else { + element_t *new_elem = create_element(data, list->pos, list->pos->next); + if (NULL == new_elem) { + return false; + } + if (!dll_is_tail(*list)) { + list->pos->next->prev = new_elem; + } + list->pos->next = new_elem; + list->pos = new_elem; + } + return true; +} + +bool dll_push(dll *list, int data) { + if (dll_is_empty(*list)) { + element_t *elem = create_element(data, NULL, NULL); + if (NULL == elem) { + return false; + } + list->head = list->pos = elem; + } else { + element_t *new_elem = create_element(data, NULL, list->head); + if (NULL == new_elem) { + return false; + } + list->head->prev = new_elem; + list->head = new_elem; + list->pos = new_elem; + } + return true; +} + +bool dll_extract(dll *list, int *val) { + bool ret = dll_value(*list, val); + if (!ret) { + return false; + } + element_t *elem = list->pos; + if (dll_is_tail(*list) && dll_is_head(*list)) { + list->head = list->pos = NULL; + } else if (dll_is_tail(*list)) { + list->pos = list->pos->prev; + list->pos->next = NULL; + } else if (dll_is_head(*list)) { + list->pos = list->pos->next; + list->pos->prev = NULL; + list->head = list->pos; + } else { + elem->prev->next = list->pos->next; + elem->next->prev = list->pos->prev; + list->pos = elem->next; + } + free(elem); + return true; +} +bool dll_pop(dll *list, int *val) { + dll_move_to_head(list); + bool ret = dll_value(*list, val); + if (!ret) { + return false; + } + element_t *elem = list->head; + if (dll_is_tail(*list) && dll_is_head(*list)) { + list->head = list->pos = NULL; + } else { + list->head->next->prev = NULL; + list->pos = list->head = list->head->next; + } + free(elem); + return true; +} + +void dll_clear(dll *list) { + dll_move_to_head(list); + int val = 0; + while (dll_pop(list, &val)) { + // we do nothing + } +}