From: Lukáš Jiřiště Date: Wed, 30 Jul 2025 19:05:55 +0000 (+0200) Subject: Add a ft_tree structure X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=606c8b9e7d20e4875eacedbc29065e071ef9ce59;p=Libft.git Add a ft_tree structure Add a non-hardened naive untested ft_tree structure. --- diff --git a/Makefile b/Makefile index 4b05fc2..aeb972a 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,14 @@ SRCstruct:= ft_stack_free.c \ ft_stack_pop_forget.c \ ft_stack_push.c \ ft_stack_top.c \ + ft_tree_init.c \ + ft_tree_append_child.c \ + *ft_tree_access_child.c \ + *ft_tree_access_data.c \ + ft_tree_erase_child.c \ + ft_tree_replace_with_child.c \ + ft_tree_forget_child.c \ + ft_tree_free.c \ SRCparse:= ft_parse.c \ ft_parsing_table_init.c \ diff --git a/ft_struct/ft_tree_access_child.c b/ft_struct/ft_tree_access_child.c new file mode 100644 index 0000000..50bc215 --- /dev/null +++ b/ft_struct/ft_tree_access_child.c @@ -0,0 +1,7 @@ +#include "ft_struct.h" +#include "libft.h" + +t_tree_node *ft_tree_access_child(t_tree_node *tree_node, size_t i) +{ + return (ft_vec_access(&tree_node->children, i)); +} diff --git a/ft_struct/ft_tree_access_data.c b/ft_struct/ft_tree_access_data.c new file mode 100644 index 0000000..1dc5b54 --- /dev/null +++ b/ft_struct/ft_tree_access_data.c @@ -0,0 +1,6 @@ +#include "ft_struct.h" + +void *ft_tree_access_data(t_tree_node *tree_node) +{ + return (tree_node->data); +} diff --git a/ft_struct/ft_tree_append_child.c b/ft_struct/ft_tree_append_child.c new file mode 100644 index 0000000..ef68334 --- /dev/null +++ b/ft_struct/ft_tree_append_child.c @@ -0,0 +1,15 @@ +#include "ft_struct.h" +#include "libft.h" + +t_ft_stat ft_tree_append_child(t_tree_node *tree_node, void *element) +{ + t_tree_node new_node; + t_ft_stat res; + + res = ft_tree_init(&new_node); + if (res != success) + return res; + new_node.data = element; + res = ft_vec_append(&tree_node->children, &new_node); + return (res); +} diff --git a/ft_struct/ft_tree_erase_child.c b/ft_struct/ft_tree_erase_child.c new file mode 100644 index 0000000..d80aef6 --- /dev/null +++ b/ft_struct/ft_tree_erase_child.c @@ -0,0 +1,11 @@ +#include "ft_struct.h" + +void ft_tree_erase_child(t_tree_node *tree_node, size_t i, void (*free_el)(void *)) +{ + t_tree_node *child_to_erase; + + child_to_erase = ft_tree_access_child(tree_node, i); + ft_tree_free(child_to_erase, free_el); + ft_tree_forget_child(tree_node, i); + return ; +} diff --git a/ft_struct/ft_tree_forget_child.c b/ft_struct/ft_tree_forget_child.c new file mode 100644 index 0000000..b74e8e1 --- /dev/null +++ b/ft_struct/ft_tree_forget_child.c @@ -0,0 +1,8 @@ +#include "ft_struct.h" +#include "libft.h" + +void ft_tree_forget_child(t_tree_node *tree_node, size_t i) +{ + ft_vec_forget(&tree_node->children, i); + return ; +} diff --git a/ft_struct/ft_tree_free.c b/ft_struct/ft_tree_free.c new file mode 100644 index 0000000..20c096f --- /dev/null +++ b/ft_struct/ft_tree_free.c @@ -0,0 +1,19 @@ +#include "ft_struct.h" +#include "libft.h" + +void ft_tree_free(t_tree *tree, void (*free_el)(void *)) +{ + size_t i; + + i = 0; + while (i < tree->children.size) + { + ft_tree_free(ft_tree_access_child(tree, i), free_el); + ++i; + } + free_el(tree->data); + ft_vec_free(&tree->children, NULL); + ft_tree_init(tree); + return ; +} + diff --git a/ft_struct/ft_tree_init.c b/ft_struct/ft_tree_init.c new file mode 100644 index 0000000..14e4f09 --- /dev/null +++ b/ft_struct/ft_tree_init.c @@ -0,0 +1,8 @@ +#include "ft_struct.h" +#include "libft.h" + +t_ft_stat ft_tree_init(t_tree *tree) +{ + tree->data = NULL; + return (ft_vec_init(&tree->children, sizeof(t_tree_node))); +} diff --git a/ft_struct/ft_tree_replace_with_child.c b/ft_struct/ft_tree_replace_with_child.c new file mode 100644 index 0000000..3cdce97 --- /dev/null +++ b/ft_struct/ft_tree_replace_with_child.c @@ -0,0 +1,21 @@ +#include "ft_struct.h" +#include "libft.h" + +void ft_tree_replace_with_child(t_tree_node *tree_node, size_t i, void (*free_el)(void *)) +{ + t_tree_node *child; + t_ft_stat res; + + child = ft_tree_access_child(tree_node, i); + if (!child) + return ; + res = ft_vec_insert_range(&tree_node->children, child->children.vec, child->children.size, i); + if (res != success) + return ; + i += child->children.size; + free_el(tree_node->data); + tree_node->data = child->data; + ft_vec_free(&child->children, NULL); + ft_vec_forget(&tree_node->children, i); + return ; +} diff --git a/inc/ft_struct.h b/inc/ft_struct.h index 55ae3ed..6d5571a 100644 --- a/inc/ft_struct.h +++ b/inc/ft_struct.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/20 16:59:43 by ljiriste #+# #+# */ -/* Updated: 2025/03/26 20:38:56 by ljiriste ### ########.fr */ +/* Updated: 2025/07/30 20:56:33 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,6 +32,26 @@ void *ft_stack_pop(t_stack *stack, void (*free_el)(void *)); void *ft_stack_pop_forget(t_stack *stack); void ft_stack_free(t_stack *stack, void (*free_el)(void *)); +// t_vec reserves memory for 8 elements at first +// it may be beneficial to add a member defining the number of children +// and let a function reserve that number in the t_vec to save some space +typedef struct s_tree_node +{ + void *data; + t_vec children; +} t_tree_node; + +typedef t_tree_node t_tree; + +t_ft_stat ft_tree_init(t_tree *tree); +t_ft_stat ft_tree_append_child(t_tree_node *tree_node, void *element); +t_tree_node *ft_tree_access_child(t_tree_node *tree_node, size_t i); +void *ft_tree_access_data(t_tree_node *tree_node); +void ft_tree_erase_child(t_tree_node *tree_node, size_t i, void (*free_el)(void *)); +void ft_tree_replace_with_child(t_tree_node *tree_node, size_t i, void (*free_el)(void *)); +void ft_tree_forget_child(t_tree_node *tree_node, size_t i); +void ft_tree_free(t_tree *tree, void (*free_el)(void *)); + # ifdef __cplusplus } # endif // __cplusplus