From ef53a1371ae52b5a1ea10f8dc1d8062666031449 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Wed, 20 Aug 2025 12:04:15 -0500 Subject: [PATCH] feat(search tree): implemented in order traversal for search tree --- Include/Fledasty/Trees/BinarySearchTree.h | 233 +++++++++++++--------- Tests/Main.c | 8 + 2 files changed, 150 insertions(+), 91 deletions(-) diff --git a/Include/Fledasty/Trees/BinarySearchTree.h b/Include/Fledasty/Trees/BinarySearchTree.h index a000c47..320fe24 100644 --- a/Include/Fledasty/Trees/BinarySearchTree.h +++ b/Include/Fledasty/Trees/BinarySearchTree.h @@ -33,98 +33,149 @@ #include "../Utils/Error.h" -#define FLEDASTY_BINARY_SEARCH_TREE_DEFINE(key_type, value_type, name) \ -typedef struct FledastyBinarySearchTreeNode_##name { \ - key_type key; \ - value_type value; \ - \ - struct FledastyBinarySearchTreeNode_##name *parent, *left, *right; \ -} FledastyBinarySearchTreeNode_##name; \ - \ -typedef struct { \ - size_t size, depth; \ - FledastyBinarySearchTreeNode_##name *top; \ -} FledastyBinarySearchTree_##name; \ - \ -FledastyError fledasty_binary_search_tree_##name##_free(FledastyBinarySearchTree_##name *current_binary_search_tree); \ - \ -FledastyError fledasty_binary_search_tree_##name##_insert(FledastyBinarySearchTree_##name *current_binary_search_tree, key_type key, value_type value); \ +#define FLEDASTY_BINARY_SEARCH_TREE_DEFINE(key_type, value_type, name) \ +typedef struct FledastyBinarySearchTreeNode_##name { \ + key_type key; \ + value_type value; \ + \ + struct FledastyBinarySearchTreeNode_##name *parent, *left, *right; \ +} FledastyBinarySearchTreeNode_##name; \ + \ +typedef struct { \ + size_t size, depth; \ + FledastyBinarySearchTreeNode_##name *top; \ +} FledastyBinarySearchTree_##name; \ + \ +FledastyError fledasty_binary_search_tree_##name##_free(FledastyBinarySearchTree_##name *current_binary_search_tree); \ + \ +FledastyError fledasty_binary_search_tree_##name##_insert(FledastyBinarySearchTree_##name *current_binary_search_tree, key_type key, value_type value); \ + \ +FledastyBinarySearchTreeNode_##name **fledasty_binary_search_tree_##name##_in_order_traversal(FledastyBinarySearchTree_##name *current_binary_search_tree); -#define FLEDASTY_BINARY_SEARCH_TREE_IMPLEMENT(key_type, value_type, name, key_less_than_function) \ -FledastyError fledasty_binary_search_tree_##name##_free(FledastyBinarySearchTree_##name *current_binary_search_tree) { \ - if (current_binary_search_tree != NULL) { \ - return FLEDASTY_ERROR_INVALID_POINTER; \ - } \ - \ - FledastyBinarySearchTreeNode_##name *current_node = current_binary_search_tree->top; \ - while (current_node != NULL) { \ - if (current_node->left != NULL) { \ - current_node = current_node->left; \ - } else if (current_node->right != NULL) { \ - current_node = current_node->right; \ - } else if (current_node->parent != NULL) { \ - current_node = current_node->parent; \ - if (current_node->left != NULL) { \ - if (hallocy_free(current_node->left) != HALLOCY_ERROR_NONE) { \ - return FLEDASTY_ERROR_FAILED_ALLOCATION; \ - } \ - \ - current_node->left = NULL; \ - } else { \ - if (hallocy_free(current_node->right) != HALLOCY_ERROR_NONE) { \ - return FLEDASTY_ERROR_FAILED_ALLOCATION; \ - } \ - \ - current_node->right = NULL; \ - } \ - } else { \ - hallocy_free(current_node); \ - current_node = NULL; \ - } \ - } \ - \ - return FLEDASTY_ERROR_NONE; \ -} \ - \ -FledastyError fledasty_binary_search_tree_##name##_insert(FledastyBinarySearchTree_##name *current_binary_search_tree, key_type key, value_type value) { \ - if (current_binary_search_tree == NULL) { \ - return FLEDASTY_ERROR_INVALID_POINTER; \ - } \ - \ - FledastyBinarySearchTreeNode_##name *new_node = (FledastyBinarySearchTreeNode_##name*)hallocy_malloc(sizeof(FledastyBinarySearchTreeNode_##name)); \ - \ - new_node->left = NULL; \ - new_node->right = NULL; \ - new_node->parent = NULL; \ - \ - new_node->key = key; \ - new_node->value = value; \ - \ - if (current_binary_search_tree->top == NULL) { \ - current_binary_search_tree->top = new_node; \ - } else { \ - FledastyBinarySearchTreeNode_##name *current_node = current_binary_search_tree->top; \ - while (new_node->parent == NULL) { \ - if (key_less_than_function(key, current_node->key)) { \ - if (current_node->left == NULL) { \ - new_node->parent = current_node; \ - current_node->left = new_node; \ - } else { \ - current_node = current_node->left; \ - } \ - } else { \ - if (current_node->right == NULL) { \ - new_node->parent = current_node; \ - current_node->right = new_node; \ - } else { \ - current_node = current_node->right; \ - } \ - } \ - } \ - } \ - \ - current_binary_search_tree->size += 1; \ - return FLEDASTY_ERROR_NONE; \ +#define FLEDASTY_BINARY_SEARCH_TREE_IMPLEMENT(key_type, value_type, name, key_less_than_function) \ +FledastyError fledasty_binary_search_tree_##name##_free(FledastyBinarySearchTree_##name *current_binary_search_tree) { \ + if (current_binary_search_tree != NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyBinarySearchTreeNode_##name *current_node = current_binary_search_tree->top; \ + while (current_node != NULL) { \ + if (current_node->left != NULL) { \ + current_node = current_node->left; \ + } else if (current_node->right != NULL) { \ + current_node = current_node->right; \ + } else if (current_node->parent != NULL) { \ + current_node = current_node->parent; \ + if (current_node->left != NULL) { \ + if (hallocy_free(current_node->left) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_node->left = NULL; \ + } else { \ + if (hallocy_free(current_node->right) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_node->right = NULL; \ + } \ + } else { \ + hallocy_free(current_node); \ + current_node = NULL; \ + } \ + } \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_binary_search_tree_##name##_insert(FledastyBinarySearchTree_##name *current_binary_search_tree, key_type key, value_type value) { \ + if (current_binary_search_tree == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyBinarySearchTreeNode_##name *new_node = (FledastyBinarySearchTreeNode_##name*)hallocy_malloc(sizeof(FledastyBinarySearchTreeNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->left = NULL; \ + new_node->right = NULL; \ + new_node->parent = NULL; \ + \ + new_node->key = key; \ + new_node->value = value; \ + \ + if (current_binary_search_tree->top == NULL) { \ + current_binary_search_tree->top = new_node; \ + } else { \ + FledastyBinarySearchTreeNode_##name *current_node = current_binary_search_tree->top; \ + while (new_node->parent == NULL) { \ + if (key_less_than_function(key, current_node->key)) { \ + if (current_node->left == NULL) { \ + new_node->parent = current_node; \ + current_node->left = new_node; \ + } else { \ + current_node = current_node->left; \ + } \ + } else { \ + if (current_node->right == NULL) { \ + new_node->parent = current_node; \ + current_node->right = new_node; \ + } else { \ + current_node = current_node->right; \ + } \ + } \ + } \ + } \ + \ + current_binary_search_tree->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyBinarySearchTreeNode_##name **fledasty_binary_search_tree_##name##_in_order_traversal(FledastyBinarySearchTree_##name *current_binary_search_tree) { \ + if (current_binary_search_tree == NULL) { \ + return NULL; \ + } \ + \ + FledastyBinarySearchTreeNode_##name **in_order_list = (FledastyBinarySearchTreeNode_##name**)hallocy_malloc(current_binary_search_tree->size * sizeof(FledastyBinarySearchTreeNode_##name*)); \ + if (in_order_list == NULL) { \ + return NULL; \ + } \ + \ + size_t current_index = 0, current_stack_size = 0; \ + bool *added_stack = (bool*)hallocy_calloc(current_binary_search_tree->size + 1, sizeof(bool)); \ + if (added_stack == NULL) { \ + return NULL; \ + } \ + \ + FledastyBinarySearchTreeNode_##name *current_node = current_binary_search_tree->top; \ + while (current_stack_size < current_binary_search_tree->size) { \ + if (current_node->left != NULL && !added_stack[current_index + 1]) { \ + current_node = current_node->left; \ + current_index += 1; \ + } else { \ + if (!added_stack[current_index]) { \ + in_order_list[current_stack_size] = current_node; \ + current_stack_size += 1; \ + added_stack[current_index] = true; \ + if (current_node->right != NULL) { \ + current_node = current_node->right; \ + current_index += 1; \ + added_stack[current_index] = false; \ + } \ + } else { \ + current_node = current_node->parent; \ + added_stack[current_index + 1] = false; \ + current_index -= 1; \ + } \ + } \ + } \ + \ + if (hallocy_free(added_stack) != HALLOCY_ERROR_NONE) { \ + return NULL; \ + } \ + \ + return in_order_list; \ } #endif diff --git a/Tests/Main.c b/Tests/Main.c index 810c645..da9e419 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -329,6 +329,14 @@ int main() { fledasty_binary_search_tree_int_int_insert(&test_search_tree, 10, 20); fledasty_binary_search_tree_int_int_insert(&test_search_tree, 7, 14); + FledastyBinarySearchTreeNode_int_int **in_order_result = fledasty_binary_search_tree_int_int_in_order_traversal(&test_search_tree); + if (in_order_result != NULL) { + for (int i = 0; i < test_search_tree.size; i += 1) { + printf("%d\n", in_order_result[i]->key); + } + } + + hallocy_free(in_order_result); fledasty_binary_search_tree_int_int_free(&test_search_tree); printf("Done\n"); return 0;