void *ft_tree_access_data(t_tree_node *tree_node)
{
- return (tree_node->data);
+ return (&tree_node->data);
}
t_ft_stat ft_tree_append_child(t_tree_node *tree_node, void *element)
{
- t_tree_node new_node;
+ t_tree_node *new_node;
t_ft_stat res;
- res = ft_tree_init(&new_node);
+ res = ft_vec_append_empty(&tree_node->children);
if (res != success)
- return res;
- new_node.data = element;
- res = ft_vec_append(&tree_node->children, &new_node);
- return (res);
+ return (res);
+ new_node = ft_tree_access_child(tree_node, tree_node->children.size - 1);
+ new_node->parent = tree_node;
+ res = ft_vec_init(&new_node->children, tree_node->children.el_size);
+ if (res != success)
+ {
+ ft_tree_forget_child(tree_node, tree_node->children.size - 1);
+ return (res);
+ }
+ ft_memcpy(&new_node->data, element, new_node->children.el_size - sizeof(t_tree_node));
+ return (success);
}
t_tree_node *child_to_erase;
child_to_erase = ft_tree_access_child(tree_node, i);
- ft_tree_free(child_to_erase, free_el);
+ while (child_to_erase->children.size > 0)
+ ft_tree_erase_child(child_to_erase, 0, free_el);
+ if (free_el)
+ free_el(&child_to_erase->data);
ft_tree_forget_child(tree_node, i);
return ;
}
void ft_tree_free(t_tree *tree, void (*free_el)(void *))
{
- size_t i;
+ t_tree_node *root;
- 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);
+ root = *tree;
+ while (root->children.size > 0)
+ ft_tree_erase_child(root, 0, free_el);
+ if (free_el)
+ free_el(&root->data);
+ ft_vec_free(&root->children, NULL);
return ;
}
-
#include "ft_struct.h"
#include "libft.h"
+#include <stdlib.h>
-t_ft_stat ft_tree_init(t_tree *tree)
+t_ft_stat ft_tree_init(t_tree *tree, size_t el_size)
{
- tree->data = NULL;
- return (ft_vec_init(&tree->children, sizeof(t_tree_node)));
+ t_tree_node *root;
+
+ root = malloc(sizeof(t_tree_node) + el_size);
+ if (!root)
+ return (alloc_fail);
+ root->parent = NULL;
+ *tree = root;
+ return (ft_vec_init(&root->children, sizeof(t_tree_node) + el_size));
}
if (res != success)
return ;
i += child->children.size;
- free_el(tree_node->data);
- tree_node->data = child->data;
+ if (free_el)
+ free_el(&tree_node->data);
+ ft_memcpy(&tree_node->data, &child->data, tree_node->children.size - sizeof(t_tree_node));
ft_vec_free(&child->children, NULL);
ft_vec_forget(&tree_node->children, i);
return ;
/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/20 16:59:43 by ljiriste #+# #+# */
-/* Updated: 2025/07/30 20:56:33 by ljiriste ### ########.fr */
+/* Updated: 2025/07/31 08:09:13 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
// 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
+//
+// element size is stored in the children t_vec, because children.size = sizeof(t_tree_node) + el_size;
+// Making the data part of the node makes the el_size fixed - use union if needed
+typedef struct s_tree_node t_tree_node;
+
+struct s_tree_node
{
- void *data;
- t_vec children;
-} t_tree_node;
+ t_tree_node *parent;
+ t_vec children;
+ char data[];
+};
-typedef t_tree_node t_tree;
+typedef t_tree_node *t_tree;
-t_ft_stat ft_tree_init(t_tree *tree);
+t_ft_stat ft_tree_init(t_tree *tree, size_t el_size);
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);