/// @file ndtree.h /// @brief N-Dimensional tree. /// @copyright (c) 2014-2022 This file is distributed under the MIT License. /// See LICENSE.md for details. #pragma once // ============================================================================ // Opaque types. /// @brief Node of the tree. typedef struct ndtree_node_t ndtree_node_t; /// @brief The tree itself. typedef struct ndtree_t ndtree_t; /// @brief Iterator for traversing the tree. typedef struct ndtree_iter_t ndtree_iter_t; // ============================================================================ // Comparison functions. /// @brief Function for comparing elements in the tree. typedef int (*ndtree_tree_cmp_f)(ndtree_t *tree, void *lhs, void *rhs); /// @brief Callback to call on elements of the tree. typedef void (*ndtree_tree_node_f)(ndtree_t *tree, ndtree_node_t *node); // ============================================================================ // Node management functions. /// @brief Allocate memory for a node. /// @return Pointer to the allocated node. ndtree_node_t *ndtree_node_alloc(); /// @brief Allocate memory for a node and sets its value. /// @param value Value to associated node. /// @return Pointer to the allocated node. ndtree_node_t *ndtree_node_create(void *value); /// @brief Initializes the already allocated node. /// @param node The node itself. /// @param value The value associated to the node. /// @return Pointer to the node itself. ndtree_node_t *ndtree_node_init(ndtree_node_t *node, void *value); /// @brief Sets the value of the given node. /// @param node The node to manipulate. /// @param value The value associated to the node. void ndtree_node_set_value(ndtree_node_t *node, void *value); /// @brief Provides access to the value associated to a node. /// @param node The node itself. /// @return The value associated to the node. void *ndtree_node_get_value(ndtree_node_t *node); /// @brief Sets the given node as root of the tree. /// @param tree The tree. /// @param node The node to set as root. void ndtree_set_root(ndtree_t *tree, ndtree_node_t *node); /// @brief Creates a new node and assigns it as root of the tree. /// @param tree The tree. /// @param value The value associated to the node. /// @return The newly created node. ndtree_node_t *ndtree_create_root(ndtree_t *tree, void *value); /// @brief Provides access to the root of the tree. /// @param tree The tree. /// @return Pointer to the node. ndtree_node_t *ndtree_get_root(ndtree_t *tree); /// @brief Adds the given `child` as child of `parent`. /// @param tree The tree. /// @param parent The `parent` node. /// @param child The new `child` node. void ndtree_add_child_to_node(ndtree_t *tree, ndtree_node_t *parent, ndtree_node_t *child); /// @brief Creates a new node and sets it as child of `parent`. /// @param tree The tree. /// @param parent The `parent` node. /// @param value Value associated with the new child. /// @return Pointer to the newly created child node. ndtree_node_t *ndtree_create_child_of_node(ndtree_t *tree, ndtree_node_t *parent, void *value); /// @brief Counts the number of children of the given node. /// @param node The node of which we count the children. /// @return The number of children. unsigned int ndtree_node_count_children(ndtree_node_t *node); /// @brief Deallocate a node. /// @param node The node to destroy. void ndtree_node_dealloc(ndtree_node_t *node); // ============================================================================ // Tree management functions. /// @brief Allocate memory for a tree. /// @return Pointer to the allocated tree. ndtree_t *ndtree_tree_alloc(); /// @brief Allocate memory for a tree and sets the function used to compare nodes. /// @param cmp Function used to compare elements of the tree. /// @return Pointer to the allocated tree. ndtree_t *ndtree_tree_create(ndtree_tree_cmp_f cmp); /// @brief Deallocate a node. /// @param tree The tree to destroy. /// @param node_cb The function called on each element of the tree before destroying the tree. void ndtree_tree_dealloc(ndtree_t *tree, ndtree_tree_node_f node_cb); /// @brief Initializes the tree. /// @param tree The tree to initialize. /// @param cmp The compare function to associate to the tree. /// @return Pointer to tree itself. ndtree_t *ndtree_tree_init(ndtree_t *tree, ndtree_tree_cmp_f cmp); /// @brief Searches the node inside the tree with the given value. /// @param tree The tree. /// @param cmp The node compare function. /// @param value The value to search. /// @return Node associated with the value. ndtree_node_t *ndtree_tree_find(ndtree_t *tree, ndtree_tree_cmp_f cmp, void *value); /// @brief Searches the given value among the children of node. /// @param tree The tree. /// @param node The node under which we search. /// @param cmp The node compare function. /// @param value The value to search. /// @return Node associated with the value. ndtree_node_t *ndtree_node_find(ndtree_t *tree, ndtree_node_t *node, ndtree_tree_cmp_f cmp, void *value); /// @brief Returns the size of the tree. /// @param tree The tree. /// @return The size of the tree. unsigned int ndtree_tree_size(ndtree_t *tree); /// @brief Removes the node from the given tree. /// @param tree The tree. /// @param node The node to remove. /// @param node_cb The function called on the node before removing it. /// @return Returns 1 if the node was removed, 0 otherwise. /// @details /// Optionally the node callback can be provided to dealloc node and/or /// user data. Use ndtree_tree_node_dealloc default callback to deallocate /// node created by ndtree_tree_insert(...). int ndtree_tree_remove_node_with_cb(ndtree_t *tree, ndtree_node_t *node, ndtree_tree_node_f node_cb); /// @brief Removes the node from the given tree. /// @param tree The tree. /// @param value The value to search. /// @param node_cb The function called on the node before removing it. /// @return Returns 1 if the value was removed, 0 otherwise. /// @details /// Optionally the node callback can be provided to dealloc node and/or /// user data. Use ndtree_tree_node_dealloc default callback to deallocate /// node created by ndtree_tree_insert(...). int ndtree_tree_remove_with_cb(ndtree_t *tree, void *value, ndtree_tree_node_f node_cb); // ============================================================================ // Iterators. /// @brief Allocate the memory for the iterator. /// @return Pointer to the allocated iterator. ndtree_iter_t *ndtree_iter_alloc(); /// @brief Deallocate the memory for the iterator. /// @param iter Pointer to the allocated iterator. void ndtree_iter_dealloc(ndtree_iter_t *iter); /// @brief Initializes the iterator the the first child of the node. /// @param node The node of which we want to iterate the children. /// @param iter The iterator we want to initialize. /// @return Pointer to the first node of the list. ndtree_node_t *ndtree_iter_first(ndtree_node_t *node, ndtree_iter_t *iter); /// @brief Initializes the iterator the the last child of the node. /// @param node The node of which we want to iterate the children. /// @param iter The iterator we want to initialize. /// @return Pointer to the last node of the list. ndtree_node_t *ndtree_iter_last(ndtree_node_t *node, ndtree_iter_t *iter); /// @brief Moves the iterator to the next element. /// @param iter The iterator. /// @return Pointer to the next element. ndtree_node_t *ndtree_iter_next(ndtree_iter_t *iter); /// @brief Moves the iterator to the previous element. /// @param iter The iterator. /// @return Pointer to the previous element. ndtree_node_t *ndtree_iter_prev(ndtree_iter_t *iter); // ============================================================================ // Tree visiting functions. /// @brief Run a visit of the tree (DFS). /// @param tree The tree to visit. /// @param enter_fun Function to call when entering a node. /// @param exit_fun Function to call when exiting a node. void ndtree_tree_visitor(ndtree_t *tree, ndtree_tree_node_f enter_fun, ndtree_tree_node_f exit_fun);