feat(tree): implement free function

pull/5/head
Jef Roosens 2023-01-20 11:07:33 +01:00 committed by Chewing_Bever
parent 935a610b7e
commit 910d7bc3bb
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 54 additions and 7 deletions

View File

@ -4,6 +4,8 @@ vieter_tree_node *vieter_tree_node_init() {
return calloc(1, sizeof(vieter_tree_node)); return calloc(1, sizeof(vieter_tree_node));
} }
void vieter_tree_node_free(vieter_tree_node *node) { free(node); }
void vieter_tree_node_add_child(vieter_tree_node *parent, uint64_t key, void vieter_tree_node_add_child(vieter_tree_node *parent, uint64_t key,
vieter_tree_node *child) { vieter_tree_node *child) {
if (parent == NULL) { if (parent == NULL) {
@ -121,17 +123,17 @@ vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root,
if (target->left == NULL && target->right == NULL) { if (target->left == NULL && target->right == NULL) {
vieter_tree_node_add_child(target->parent, target->key, NULL); vieter_tree_node_add_child(target->parent, target->key, NULL);
free(target); vieter_tree_node_free(target);
} else if ((target->left == NULL) ^ (target->right == NULL)) { } else if ((target->left == NULL) ^ (target->right == NULL)) {
vieter_tree_node *child = vieter_tree_node *child =
target->left != NULL ? target->left : target->right; target->left != NULL ? target->left : target->right;
if (target->parent != NULL) { if (target->parent != NULL) {
vieter_tree_node_add_child(target->parent, child->key, child); vieter_tree_node_add_child(target->parent, child->key, child);
free(target); vieter_tree_node_free(target);
} else { } else {
vieter_tree_node_replace(target, child); vieter_tree_node_replace(target, child);
free(child); vieter_tree_node_free(child);
} }
} else { } else {
@ -151,7 +153,7 @@ vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root,
target->key = replacement->key; target->key = replacement->key;
target->data = replacement->data; target->data = replacement->data;
free(replacement); vieter_tree_node_free(replacement);
} }
return vieter_tree_ok; return vieter_tree_ok;

View File

@ -14,6 +14,8 @@ typedef struct vieter_tree_node {
vieter_tree_node *vieter_tree_node_init(); vieter_tree_node *vieter_tree_node_init();
void vieter_tree_node_free(vieter_tree_node *node);
vieter_tree_error vieter_tree_node_insert(vieter_tree_node *root, uint64_t key, void *data); vieter_tree_error vieter_tree_node_insert(vieter_tree_node *root, uint64_t key, void *data);
vieter_tree_error vieter_tree_node_search_node(vieter_tree_node **out, vieter_tree_node *root, uint64_t key); vieter_tree_error vieter_tree_node_search_node(vieter_tree_node **out, vieter_tree_node *root, uint64_t key);
@ -21,8 +23,6 @@ vieter_tree_error vieter_tree_node_search(void **out, vieter_tree_node *root, ui
vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root, uint64_t key); vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root, uint64_t key);
vieter_tree_node *vieter_tree_node_successor(vieter_tree_node *node);
void vieter_tree_node_replace(vieter_tree_node *to_replace, vieter_tree_node *replacement); void vieter_tree_node_replace(vieter_tree_node *to_replace, vieter_tree_node *replacement);
#endif #endif

View File

@ -57,3 +57,43 @@ vieter_tree_error vieter_tree_remove(void **out, vieter_tree *tree,
return vieter_tree_ok; return vieter_tree_ok;
} }
void vieter_tree_free(vieter_tree *tree) {
if (tree->size == 0) {
goto end;
}
uint64_t capacity = 4;
uint64_t size = 1;
vieter_tree_node **stack = malloc(capacity * sizeof(vieter_tree_node *));
stack[0] = tree->root;
vieter_tree_node *node;
while (size > 0) {
node = stack[size - 1];
size--;
if (size + 2 > capacity) {
capacity *= 2;
stack = realloc(stack, capacity * sizeof(vieter_tree_node *));
}
if (node->left != NULL) {
stack[size] = node->left;
size++;
}
if (node->right != NULL) {
stack[size] = node->right;
size++;
}
vieter_tree_node_free(node);
}
free(stack);
end:
free(tree);
}

View File

@ -9,7 +9,7 @@ void test_init() {
vieter_tree *tree = vieter_tree_init(); vieter_tree *tree = vieter_tree_init();
TEST_CHECK(tree != NULL); TEST_CHECK(tree != NULL);
TEST_SIZE(tree, 0); TEST_SIZE(tree, 0);
/* vieter_tree_free(tree); */ vieter_tree_free(tree);
} }
void test_insert() { void test_insert() {
@ -27,6 +27,8 @@ void test_insert() {
TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_already_present); TEST_CHECK(vieter_tree_insert(tree, i, NULL) == vieter_tree_already_present);
TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok); TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok);
} }
vieter_tree_free(tree);
} }
void test_remove() { void test_remove() {
@ -42,7 +44,10 @@ void test_remove() {
TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok); TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_ok);
TEST_CHECK(vieter_tree_remove(&out, tree, i) == vieter_tree_ok); TEST_CHECK(vieter_tree_remove(&out, tree, i) == vieter_tree_ok);
TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_not_present); TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_not_present);
TEST_SIZE(tree, 25 - i - 1);
} }
vieter_tree_free(tree);
} }
TEST_LIST = { TEST_LIST = {