From 98f158e1f5df2a4842eeb2aea51bf9169db7e2b3 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 19 Jan 2023 22:23:19 +0100 Subject: [PATCH] feat(tree): started standard binary tree --- Makefile | 4 +++ include/vieter_tree.h | 21 +++++++++++-- src/tree/node.c | 61 ++++++++++++++++++++++++++++++++++++ src/tree/node.h | 14 +++++++-- src/tree/tree.c | 57 +++++++++++++++++++++++++++++++-- test/tree/test_binary_tree.c | 32 +++++++++++++++++++ 6 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 src/tree/node.c create mode 100644 test/tree/test_binary_tree.c diff --git a/Makefile b/Makefile index 04c6dd3..411a033 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,10 @@ $(TARGETS_TEST): test-%: % $(TARGETS_MEM_TEST): test-mem-%: % valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes --leak-check=full ./$^ +test-mem: build-test + @ $(foreach bin,$(BINS_TEST),valgrind --tool=memcheck --error-exitcode=1 \ + --track-origins=yes --leak-check=full ./$(bin);) + .PHONY: build-test build-test: $(BINS_TEST) diff --git a/include/vieter_tree.h b/include/vieter_tree.h index 7dda9e1..be381e5 100644 --- a/include/vieter_tree.h +++ b/include/vieter_tree.h @@ -2,14 +2,29 @@ #define VIETER_TREE #include +#include typedef struct vieter_tree vieter_tree; typedef enum vieter_tree_error { - vieter_tree_ok = 0, - vieter_tree_already_present = 1 + vieter_tree_ok = 0, + vieter_tree_already_present = 1, + vieter_tree_not_present = 2 } vieter_tree_error; -vieter_tree_error vieter_tree_insert(uint64_t key, void *data); +vieter_tree *vieter_tree_init(); + +void vieter_tree_free(vieter_tree *tree); + +vieter_tree_error vieter_tree_insert(vieter_tree *tree, uint64_t key, + void *data); + +vieter_tree_error vieter_tree_search(void **out, vieter_tree *tree, + uint64_t key); + +vieter_tree_error vieter_tree_remove(void **out, vieter_tree *tree, + uint64_t key); + +uint64_t vieter_tree_size(vieter_tree *tree); #endif diff --git a/src/tree/node.c b/src/tree/node.c new file mode 100644 index 0000000..935a56d --- /dev/null +++ b/src/tree/node.c @@ -0,0 +1,61 @@ +#include "node.h" + +vieter_tree_node *vieter_tree_node_init() { + return calloc(1, sizeof(vieter_tree_node)); +} + +vieter_tree_error vieter_tree_node_insert(vieter_tree_node *node, uint64_t key, + void *data) { + vieter_tree_node *parent = node; + + while (node != NULL) { + if (node->key == key) { + return vieter_tree_already_present; + } + + parent = node; + + if (key < node->key) { + node = parent->left; + } else { + node = parent->right; + } + } + + vieter_tree_node *new_node = vieter_tree_node_init(); + new_node->key = key; + new_node->data = data; + new_node->parent = parent; + + if (key < node->key) { + parent->left = new_node; + } else { + parent->right = new_node; + } + + return vieter_tree_ok; +} + +vieter_tree_error vieter_tree_node_search(void **out, vieter_tree_node *node, + uint64_t key) { + while (node != NULL) { + if (node->key == key) { + *out = node->data; + + return vieter_tree_ok; + } + + if (key < node->key) { + node = node->left; + } else { + node = node->right; + } + } + + return vieter_tree_not_present; +} + +vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *node, + uint64_t key) { + return vieter_tree_not_present; +} diff --git a/src/tree/node.h b/src/tree/node.h index 10143ca..f22a965 100644 --- a/src/tree/node.h +++ b/src/tree/node.h @@ -1,13 +1,23 @@ -#ifndef VIETER_BALANCED_TREE_NODE -#define VIETER_BALANCED_TREE_NODE +#ifndef VIETER_TREE_NODE +#define VIETER_TREE_NODE +#include "vieter_tree.h" #include typedef struct vieter_tree_node { uint64_t key; void *data; + struct vieter_tree_node *parent; struct vieter_tree_node *left; struct vieter_tree_node *right; } vieter_tree_node; +vieter_tree_node *vieter_tree_node_init(); + +vieter_tree_error vieter_tree_node_insert(vieter_tree_node *node, uint64_t key, void *data); + +vieter_tree_error vieter_tree_node_search(void **out, vieter_tree_node *node, uint64_t key); + +vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *node, uint64_t key); + #endif diff --git a/src/tree/tree.c b/src/tree/tree.c index 4a10d5a..725fcda 100644 --- a/src/tree/tree.c +++ b/src/tree/tree.c @@ -1,6 +1,59 @@ -#include "vieter_tree.h" #include "node.h" +#include "vieter_tree.h" struct vieter_tree { - uint64_t size; + uint64_t size; + vieter_tree_node *root; }; + +vieter_tree *vieter_tree_init() { return calloc(1, sizeof(vieter_tree)); } + +uint64_t vieter_tree_size(vieter_tree *tree) { return tree->size; } + +vieter_tree_error vieter_tree_insert(vieter_tree *tree, uint64_t key, + void *data) { + if (tree->size == 0) { + tree->root = vieter_tree_node_init(); + tree->root->key = key; + tree->root->data = data; + tree->size = 1; + + return vieter_tree_ok; + } + + vieter_tree_error res = vieter_tree_node_insert(tree->root, key, data); + + if (res != vieter_tree_ok) { + return res; + } + + tree->size++; + + return vieter_tree_ok; +} + +vieter_tree_error vieter_tree_search(void **out, vieter_tree *tree, + uint64_t key) { + if (tree->size == 0) { + return vieter_tree_not_present; + } + + return vieter_tree_node_search(out, tree->root, key); +} + +vieter_tree_error vieter_tree_remove(void **out, vieter_tree *tree, + uint64_t key) { + if (tree->size == 0) { + return vieter_tree_not_present; + } + + vieter_tree_error res = vieter_tree_node_remove(out, tree->root, key); + + if (res != vieter_tree_ok) { + return res; + } + + tree->size--; + + return vieter_tree_ok; +} diff --git a/test/tree/test_binary_tree.c b/test/tree/test_binary_tree.c new file mode 100644 index 0000000..fd6bb1b --- /dev/null +++ b/test/tree/test_binary_tree.c @@ -0,0 +1,32 @@ +#include "acutest.h" +#include "vieter_tree.h" + +#define TEST_SIZE(tree, size) \ + TEST_CHECK(vieter_tree_size(tree) == size); \ + TEST_MSG("Size: %zu", vieter_tree_size(tree)) + +void test_init() { + vieter_tree *tree = vieter_tree_init(); + TEST_CHECK(tree != NULL); + TEST_SIZE(tree, 0); + /* vieter_tree_free(tree); */ +} + +void test_insert() { + vieter_tree *tree = vieter_tree_init(); + + for (uint64_t i = 0; i < 25; i++) { + TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_ok); + } + + void *out; + + for (uint64_t i = 0; i < 25; i++) { + TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_already_present); + TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok); + } +} + +TEST_LIST = { + {NULL, NULL} +};