feat(tree): implement free function

This commit is contained in:
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));
}
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;

View file

@ -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

View file

@ -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);
}