From 8660ff8bad6cfcda2b287907d79c1e65596ad262 Mon Sep 17 00:00:00 2001 From: "Claudio Maggioni (maggicl)" Date: Fri, 23 Aug 2019 20:22:55 +0200 Subject: [PATCH] Work on collections --- collections/collections.h | 49 +++++++++++++++ collections/list.c | 115 +++++++++++++++++++++++++++++++++++ collections/stack.c | 20 ++++++ list.c | 125 -------------------------------------- 4 files changed, 184 insertions(+), 125 deletions(-) create mode 100644 collections/collections.h create mode 100644 collections/list.c create mode 100644 collections/stack.c delete mode 100644 list.c diff --git a/collections/collections.h b/collections/collections.h new file mode 100644 index 0000000..9c2c973 --- /dev/null +++ b/collections/collections.h @@ -0,0 +1,49 @@ +// vim: set et sw=4 ts=4 tw=80: +#ifndef COLLECTIONS_H_INCLUDED +#define COLLECTIONS_H_INCLUDED + +#include +#include +#include + +/* + * Doubly linked list + */ + +typedef struct dl_node { + void* element; + struct dl_node* prev; + struct dl_node* next; +} dl_node_t; + +typedef struct dl_list { + dl_node_t* first; +} dl_list_t; + +extern size_t dl_list_length(const dl_list_t* self); +extern dl_node_t* dl_list_ith(const dl_list_t* self, const size_t position); +extern dl_node_t* dl_list_ith_or_last(const dl_list_t* self, + const size_t position, size_t* returned); + +extern inline dl_node_t* dl_list_alloc_node(void* element); +extern inline void dl_list_free_node(dl_node_t* node); + +extern inline void dl_list_init(dl_list_t* list); +extern inline void dl_list_destroy(dl_list_t* list); + +extern size_t dl_list_copy_slice(const dl_list_t* self, dl_list_t* destination, + const size_t from, const size_t to); + +extern int dl_list_insert(dl_list_t* self, const size_t position, + dl_node_t* node); +extern dl_node_t* dl_list_remove(dl_list_t* self, const size_t position); + +typedef struct vector { + void** elements; + size_t size; + size_t capacity; +} vector_t; + +extern void vector_init(vector_t* self, const size_t initial_capacity); + +#endif diff --git a/collections/list.c b/collections/list.c new file mode 100644 index 0000000..c9dbf37 --- /dev/null +++ b/collections/list.c @@ -0,0 +1,115 @@ +// vim: set ts=4 sw=4 tw=80 et: +#include "./collections.h" + +size_t dl_list_length(const dl_list_t* self) { + size_t length = 0; + dl_node_t* i = self->first; + + while (i != NULL) { + length++; + i = i->next; + } + + return length; +} + +dl_node_t* dl_list_ith(const dl_list_t* self, const size_t position) { + size_t found; + dl_node_t* elem = dl_list_ith_or_last(self, position, &found); + return found != position ? NULL : elem; +} + +dl_node_t* dl_list_ith_or_last(const dl_list_t* self, const size_t position, + size_t* returned) { + dl_node_t* to_reach = self->first; + size_t i; + for (i = 0; i < position && to_reach->next != NULL; i++) { + to_reach = to_reach->next; + } + *returned = i; + return to_reach; +} + +inline dl_node_t* dl_list_alloc_node(void* element) { + dl_node_t* node = malloc(sizeof(node)); + node->element = element; + node->next = NULL; + node->prev = NULL; +} + +inline void dl_list_free_node(dl_node_t* node) { + if (node->element != NULL) { + free(node->element); + } + free(node); +} + +inline void dl_list_init(dl_list_t* self) { + self->first = NULL; +} + +inline void dl_list_destroy(dl_list_t* self) { + while(self->first != NULL) { + free(dl_list_remove(self, 0)); + } +} + +size_t dl_list_copy_slice(const dl_list_t* self, dl_list_t* destination, + const size_t from, const size_t to) { + if (from >= to) { + return 0; + } + dl_list_destroy(destination); + size_t start, i; + dl_node_t* to_copy = dl_list_ith_or_last(self, to, &start); + if (to_copy == NULL) { + return 0; + } + + for(i = start; i > from; i--) { + dl_node_t* copied = malloc(sizeof(dl_node_t)); + memcpy(copied, self, sizeof(dl_node_t)); + dl_list_insert(destination, 0, copied); + } + + return start - from; +} + +int dl_list_insert(dl_list_t* self, const size_t position, dl_node_t* node) { + if (position == 0) { + node->next = self->first; + node->prev = NULL; + self->first = node; + return 0; + } + + dl_node_t* to_reach = dl_list_ith(self, position - 1); + + if (to_reach == NULL) { + return 2; + } + + to_reach->next->prev = node; + node->next = to_reach->next; + node->prev = to_reach; + to_reach->next = node; + return 0; +} + +dl_node_t* dl_list_remove(dl_list_t* self, const size_t position) { + if(position == 0) { + dl_node_t* to_remove = self->first; + self->first = to_remove->next; + return to_remove; + } + + dl_node_t* to_reach = dl_list_ith(self, position - 1); + if (to_reach == NULL || to_reach->next == NULL) { + return NULL; + } + + dl_node_t* to_remove = to_reach->next; + to_reach->next = to_reach->next->next; + to_reach->next->prev = to_reach; + return to_remove; +} diff --git a/collections/stack.c b/collections/stack.c new file mode 100644 index 0000000..f70502f --- /dev/null +++ b/collections/stack.c @@ -0,0 +1,20 @@ +// vim: set et sw=4 ts=4 tw=80: +#include "./collections.h" + +static inline void vector_expand(vector_t* self) { + if (self->size >= self->capacity) { + self->capacity *= 2; + self->elements = realloc(self->elements, + sizeof(void*) * self->capacity); + } +} + +void vector_init(vector_t* self, const size_t initial_capacity) { + self->elements = (void**) malloc(sizeof(void*) * initial_capacity); + self->size = 0; + self->capacity = initial_capacity; +} + +void vector_insert(vector_t* self, const size_t position, const void* element) { + vector_expand(self); +} diff --git a/list.c b/list.c deleted file mode 100644 index ff6f5bb..0000000 --- a/list.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#define TYPE int -//A list is one of: -// - (make-note element next) -// - '() -> NULL - -struct node { - TYPE element; - struct node* prev; - struct node* next; -}; - -typedef struct node node_t; - -typedef struct { - node* first; -} list_t; - -size_t list_length(const list_t* self) { - size_t length = 0; - node_t* i = self->first; - - while (i != NULL) { - length++; - i = self->next; - } - - return length; -} - -node_t* list_ith(const list_t* self, const size_t position) { - size_t found; - node_t* elem = list_ith_or_last(self, position, &found); - return found != position ? NULL : elem; -} - -node_t* list_ith_or_last(const list_t* self, const size_t position, - const size_t* returned) { - node_t* to_reach = self->first; - size_t i; - for (i = 0; i < position && to_reach->next != NULL; i++) { - to_reach = to_reach->next; - } - *returned = i; - return to_reach; -} - -node_t* make_node(TYPE element) { - node_t* node = malloc(sizeof(node)); - node->element = element; - node->next = NULL; - node->prev = NULL; -} - -void free_list(const list_t* list) { - while(list->first != NULL) { - free(list_remove(self, 0)); - } -} - -size_t list_copy_slice(const list_t* self, const list_t* destination, - const size_t from, const size_t to) { - if (from >= to) { - return 0; - } - free_list(destination); - size_t start, i; - node_t* to_copy = list_ith_or_last(self, to, &start); - if (to_copy == NULL) { - return 0; - } - - for(i = start; i > from; i--) { - node_t* copied = malloc(sizeof(node_t)); - memcpy(copied, src, sizeof(node_t)); - list_insert(destination, 0, copied); - } - - return start - from; -} - -int list_insert(const list_t* self, const size_t position, const node_t* node) { - if (self->first == NULL) { - return 1; - } - - if (position == 0) { - node->next = self->first; - node->prev = NULL; - self->first = node; - return 0; - } - - node_t* to_reach = list_ith(self, position - 1); - - if (to_reach == NULL) { - return 2; - } - - to_reach->next->prev = node; - node->next = to_reach->next; - node->prev = to_reach; - to_reach->next = node; - return 0; -} - -node_t* list_remove(const list_t* self, const size_t position) { - if(position == 0) { - node_t* to_remove = self->first; - self->first = to_remove->next; - return to_remove; - } - - node_t* to_reach = list_ith(self, position - 1); - if (to_reach == NULL || to_reach->next == NULL) { - return NULL; - } - - node_t* to_remove = to_reach->next; - to_reach->next = to_reach->next->next; - to_reach->next->prev = to_reach; - return to_remove; -}