diff --git a/src/tree/node.c b/src/tree/node.c index 131e932..568103e 100644 --- a/src/tree/node.c +++ b/src/tree/node.c @@ -4,6 +4,8 @@ vieter_tree_node *vieter_tree_node_init() { 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, vieter_tree_node *child) { 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) { 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)) { vieter_tree_node *child = target->left != NULL ? target->left : target->right; if (target->parent != NULL) { vieter_tree_node_add_child(target->parent, child->key, child); - free(target); + vieter_tree_node_free(target); } else { vieter_tree_node_replace(target, child); - free(child); + vieter_tree_node_free(child); } } else { @@ -151,7 +153,7 @@ vieter_tree_error vieter_tree_node_remove(void **out, vieter_tree_node *root, target->key = replacement->key; target->data = replacement->data; - free(replacement); + vieter_tree_node_free(replacement); } return vieter_tree_ok; diff --git a/src/tree/node.h b/src/tree/node.h index 68da70e..dc8cce0 100644 --- a/src/tree/node.h +++ b/src/tree/node.h @@ -14,6 +14,8 @@ typedef struct vieter_tree_node { 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_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_node *vieter_tree_node_successor(vieter_tree_node *node); - void vieter_tree_node_replace(vieter_tree_node *to_replace, vieter_tree_node *replacement); #endif diff --git a/src/tree/tree.c b/src/tree/tree.c index 725fcda..c2c7aa7 100644 --- a/src/tree/tree.c +++ b/src/tree/tree.c @@ -57,3 +57,43 @@ vieter_tree_error vieter_tree_remove(void **out, vieter_tree *tree, 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); +} diff --git a/test/tree/test_binary_tree.c b/test/tree/test_binary_tree.c index 4b1ceba..7e85ebe 100644 --- a/test/tree/test_binary_tree.c +++ b/test/tree/test_binary_tree.c @@ -9,7 +9,7 @@ void test_init() { vieter_tree *tree = vieter_tree_init(); TEST_CHECK(tree != NULL); TEST_SIZE(tree, 0); - /* vieter_tree_free(tree); */ + vieter_tree_free(tree); } 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_search(&out, tree, i) == vieter_tree_ok); } + + vieter_tree_free(tree); } 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_remove(&out, tree, i) == vieter_tree_ok); TEST_CHECK(vieter_tree_search(&out, tree, i) == vieter_tree_not_present); + TEST_SIZE(tree, 25 - i - 1); } + + vieter_tree_free(tree); } TEST_LIST = {