119 lines
2.5 KiB
C
119 lines
2.5 KiB
C
|
#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);
|
||
|
}
|