libft/ft_rb_tree.c

130 lines
2.7 KiB
C
Raw Normal View History

2024-10-20 18:09:36 +00:00
#include "libft.h"
void ft_delrbt(t_node *node, void (*f)(void *data)) {
if (!(node)) {
return;
}
ft_delrbt(node->left, f);
ft_delrbt(node->right, f);
f((void *)node);
free(node->data);
free(node);
}
2024-10-20 18:09:36 +00:00
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);
}