diff --git a/Makefile b/Makefile index 40887a5..65b2375 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: gbrochar +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2015/11/27 19:26:17 by gbrochar #+# #+# # -# Updated: 2024/10/14 20:59:43 by gbrochar ### ########.fr # +# Updated: 2024/10/20 20:09:14 by gbrochar ### ########.fr # # # # **************************************************************************** # @@ -22,7 +22,8 @@ ft_strchr.c ft_strclr.c ft_strcmp.c ft_strcpy.c ft_strdel.c ft_strdup.c \ ft_strequ.c ft_striter.c ft_striteri.c ft_strjoin.c ft_strlcat.c ft_strlen.c \ ft_strmap.c ft_strmapi.c ft_strncat.c ft_strncmp.c ft_strncpy.c ft_strnequ.c \ ft_strnew.c ft_strnstr.c ft_strrchr.c ft_strsplit.c ft_strstr.c ft_strsub.c \ -ft_strtrim.c ft_swap.c ft_tolower.c ft_toupper.c ft_lstadd_back.c ft_lstinsert.c +ft_strtrim.c ft_swap.c ft_tolower.c ft_toupper.c ft_lstadd_back.c \ +ft_lstinsert.c ft_rb_tree.c OBJ = $(SRC:.c=.o) diff --git a/ft_rb_tree.c b/ft_rb_tree.c new file mode 100644 index 0000000..85bfdc1 --- /dev/null +++ b/ft_rb_tree.c @@ -0,0 +1,118 @@ +#include "libft.h" + +void ft_putrbt(t_node *node, void (*f)(void *data)) { + if (!(node)) { + return; + } + ft_putrbt(node->left, f); + f((void *)node); + ft_putrbt(node->right, f); +} + +t_node *ft_rbt_new(void *data, size_t size) { + t_node *new = (t_node *)malloc(sizeof(t_node)); + new->data = malloc(size); + ft_memcpy(new->data, data, size); + new->left = NULL; + new->right = NULL; + new->parent = NULL; + new->color = RED; + return new; +} + +void ft_rbt_left_rotate(t_root **root, t_node *x) { + t_node *y = x->right; + x->right = y->left; + if (y->left) { + y->left->parent = x; + } + y->parent = x->parent; + if (!x->parent) { + *root = y; + } else if (x == x->parent->left) { + x->parent->left = y; + } else { + x->parent->right = y; + } + y->left = x; + x->parent = y; +} + +void ft_rbt_right_rotate(t_root **root, t_node *x) { + t_node *y = x->left; + x->left = y->right; + if (y->right) { + y->right->parent = x; + } + y->parent = x->parent; + if (!x->parent) { + *root = y; + } else if (x == x->parent->right) { + x->parent->right = y; + } else { + x->parent->left = y; + } + y->right = x; + x->parent = y; +} + +void ft_rbt_insert_fixup(t_root **root, t_node *z) { + while (z->parent && z->parent->color == RED) { + if (z->parent->parent && z->parent == z->parent->parent->left) { + t_node *y = z->parent->parent->right; + if (y && y->color == RED) { + z->parent->color = BLACK; + y->color = BLACK; + z->parent->parent->color = RED; + z = z->parent->parent; + } else { + if (z == z->parent->right) { + z = z->parent; + ft_rbt_left_rotate(root, z); + } + z->parent->color = BLACK; + z->parent->parent->color = RED; + ft_rbt_right_rotate(root, z->parent->parent); + } + } else if (z->parent->parent) { + t_node *y = z->parent->parent->left; + if (y && y->color == RED) { + z->parent->color = BLACK; + y->color = BLACK; + z->parent->parent->color = RED; + z = z->parent->parent; + } else { + if (z == z->parent->left) { + z = z->parent; + ft_rbt_right_rotate(root, z); + } + z->parent->color = BLACK; + z->parent->parent->color = RED; + ft_rbt_left_rotate(root, z->parent->parent); + } + } + } + (*root)->color = BLACK; +} + +void ft_rbt_insert(t_root **root, t_node *z, int (*f)(void *a, void *b)) { + t_node *y = NULL; + t_node *x = *root; + while (x) { + y = x; + if (f(z->data, x->data) < 0) { + x = x->left; + } else { + x = x->right; + } + } + z->parent = y; + if (y == NULL) { + *root = z; + } else if (f(z->data, y->data) < 0) { + y->left = z; + } else { + y->right = z; + } + ft_rbt_insert_fixup(root, z); +} diff --git a/libft.h b/libft.h index 35acffe..8da7af4 100644 --- a/libft.h +++ b/libft.h @@ -6,7 +6,7 @@ /* By: gbrochar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2015/11/24 12:52:28 by gbrochar #+# #+# */ -/* Updated: 2024/10/14 21:01:47 by gbrochar ### ########.fr */ +/* Updated: 2024/10/20 18:36:39 by gbrochar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,8 @@ # include # include +typedef struct s_node t_node; + typedef struct s_list { void *content; @@ -24,6 +26,26 @@ typedef struct s_list struct s_list *next; } t_list; +typedef enum e_color { + RED, + BLACK, +} t_color; + +struct s_node +{ + void *data; + t_node *parent; + t_node *left; + t_node *right; + t_color color; +}; + +typedef t_node t_root; +typedef t_node t_leaf; + +void ft_rbt_insert(t_root **root, t_node *z, int (*f)(void *a, void *b)); +t_node *ft_rbt_new(void *data, size_t size); +void ft_putrbt(t_node *node, void (*f)(void *data)); void ft_lstadd(t_list **alst, t_list *new); void ft_lstadd_back(t_list **alst, t_list *new); void ft_lstinsert(t_list **lst, t_list *new, int (*f)(t_list *a, t_list *b));