From 5177ad9a8dc6f67a81e1831495bdc5b0ed7af297 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Mar 2019 00:55:57 -0300 Subject: [PATCH] Added linkedlist node functions --- examples/linked_list_node.c | 43 +++++++++++++ src/linkedlist.h | 124 ++++++++++++++++++++++++++++++++++-- 2 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 examples/linked_list_node.c diff --git a/examples/linked_list_node.c b/examples/linked_list_node.c new file mode 100644 index 0000000..da40e3e --- /dev/null +++ b/examples/linked_list_node.c @@ -0,0 +1,43 @@ +#include +#include +#include "../src/linkedlist.h" + +LINKEDLIST_GENERATE(l, list, , , int) + +int main(int argc, char const *argv[]) +{ + list *l = l_new(); + + for (int i = 0; i < 97; i++) + l_push_back(l, i); + + // Add 99 after and 33 before every node where its data is divisible by 3 + for (list_node *node = l->head; node != NULL; node = node->next) + { + if (node->data % 3 == 0) + { + l_insert_prv(node, 33); + l_insert_nxt(node, 99); + node = node->next; // skip 99 + } + } + + size_t s = 0; + for (list_node *node = l->head; node != NULL; node = node->next, s++) + { + if (node->prev == NULL) + printf("[ %d, ", node->data); + else if (node->next == NULL) + printf("%d ]\n", node->data); + else + printf("%d, ", node->data); + } + + printf("List Head: %d\nList Tail: %d\nList Count: %d\n", l->head->data, l->tail->data, l->count); + + assert(s == l->count); + + l_free(l); + + return 0; +} diff --git a/src/linkedlist.h b/src/linkedlist.h index 7621344..ca59bbd 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -47,6 +47,7 @@ \ struct SNAME##_node_s \ { \ + struct SNAME##_s *owner; \ struct SNAME##_node_s *next; \ struct SNAME##_node_s *prev; \ T data; \ @@ -84,6 +85,14 @@ FMOD bool PFX##_empty(SNAME *_list_); \ FMOD size_t PFX##_count(SNAME *_list_); \ \ + FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element); \ + FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index); \ + FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element); \ + FMOD bool PFX##_insert_prv(SNAME##_node *node, T element); \ + FMOD bool PFX##_remove_nxt(SNAME##_node *node); \ + FMOD bool PFX##_remove_cur(SNAME##_node *node); \ + FMOD bool PFX##_remove_prv(SNAME##_node *node); \ + \ FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \ FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ @@ -95,9 +104,6 @@ /* SOURCE ********************************************************************/ #define LINKEDLIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \ \ - FMOD SNAME##_node *PFX##_new_node(T element); \ - FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index); \ - \ FMOD SNAME *PFX##_new(void) \ { \ SNAME *_list_ = malloc(sizeof(SNAME)); \ @@ -126,7 +132,7 @@ \ FMOD bool PFX##_push_front(SNAME *_list_, T element) \ { \ - SNAME##_node *node = PFX##_new_node(element); \ + SNAME##_node *node = PFX##_new_node(_list_, element); \ \ if (!node) \ return false; \ @@ -162,7 +168,7 @@ return PFX##_push_back(_list_, element); \ } \ \ - SNAME##_node *node = PFX##_new_node(element); \ + SNAME##_node *node = PFX##_new_node(_list_, element); \ \ if (!node) \ return false; \ @@ -181,7 +187,7 @@ \ FMOD bool PFX##_push_back(SNAME *_list_, T element) \ { \ - SNAME##_node *node = PFX##_new_node(element); \ + SNAME##_node *node = PFX##_new_node(_list_, element); \ \ if (!node) \ return false; \ @@ -330,13 +336,117 @@ return _list_->count; \ } \ \ - FMOD SNAME##_node *PFX##_new_node(T element) \ + FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element) \ + { \ + SNAME##_node *new_node = PFX##_new_node(node->owner, element); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->next = node->next; \ + if (node->next != NULL) \ + node->next->prev = new_node; \ + else \ + node->owner->tail = new_node; \ + \ + new_node->prev = node; \ + node->next = new_node; \ + \ + node->owner->count++; \ + \ + return true; \ + } \ + \ + FMOD bool PFX##_insert_prv(SNAME##_node *node, T element) \ + { \ + SNAME##_node *new_node = PFX##_new_node(node->owner, element); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->prev = node->prev; \ + if (node->prev != NULL) \ + node->prev->next = new_node; \ + else \ + node->owner->head = new_node; \ + \ + new_node->next = node; \ + node->prev = new_node; \ + \ + node->owner->count++; \ + \ + return true; \ + } \ + \ + FMOD bool PFX##_remove_nxt(SNAME##_node *node) \ + { \ + if (node->next == NULL) \ + return false; \ + \ + SNAME##_node *tmp = node->next; \ + \ + if (node->next != NULL) \ + { \ + node->next = node->next->next; \ + node->next->prev = node; \ + } \ + else \ + node->owner->tail = node; \ + \ + node->owner->count--; \ + \ + free(tmp); \ + \ + return true; \ + } \ + \ + FMOD bool PFX##_remove_cur(SNAME##_node *node) \ + { \ + if (node->prev != NULL) \ + node->prev->next = node->next; \ + else \ + node->owner->head = node->next; \ + \ + if (node->next != NULL) \ + node->next->prev = node->prev; \ + else \ + node->owner->tail = node->prev; \ + \ + node->owner->count--; \ + \ + free(node); \ + \ + return true; \ + } \ + \ + FMOD bool PFX##_remove_prv(SNAME##_node *node) \ + { \ + if (node->prev == NULL) \ + return false; \ + \ + SNAME##_node *tmp = node->prev; \ + \ + if (node->prev != NULL) \ + { \ + node->prev = node->prev->prev; \ + node->prev->next = node; \ + } \ + else \ + node->owner->head = node; \ + \ + free(tmp); \ + \ + return true; \ + } \ + \ + FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element) \ { \ SNAME##_node *node = malloc(sizeof(SNAME##_node)); \ \ if (!node) \ return NULL; \ \ + node->owner = _owner_; \ node->data = element; \ node->next = NULL; \ node->prev = NULL; \