#include "rbtree.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
struct rb_tree
{
int (*compare_keys)(const void *a, const void *b);
void (*destroy_key)(void *a);
void (*destroy_value)(void *a);
void (*print_key)(const void *a);
void (*print_value)(const void *a);
struct rb_node *root, *nil;
unsigned int size;
};
struct rb_tree *rb_create(int (*compare_keys_func)(const void*, const void*),
void (*destroy_key_func)(void*),
void (*destroy_value_func)(void*),
void (*print_key_func)(const void*),
void (*print_value_func)(const void*))
{
struct rb_tree *tree;
struct rb_node *temp;
tree = (struct rb_tree*)malloc(sizeof(struct rb_tree));
if (tree == NULL) return NULL;
tree->compare_keys = compare_keys_func;
tree->destroy_key = destroy_key_func;
tree->destroy_value = destroy_value_func;
tree->print_key = print_key_func;
tree->print_value = print_value_func;
tree->size = 0;
temp = tree->nil = (struct rb_node*)malloc(sizeof(struct rb_node));
temp->parent = temp->left = temp->right = temp;
temp->red = 0;
temp->key = 0;
temp = tree->root = (struct rb_node*)malloc(sizeof(struct rb_node));
temp->parent = temp->left = temp->right = tree->nil;
temp->red = 0;
temp->key = 0;
return tree;
}
int rb_isempty(struct rb_tree *tree)
{
return (tree->root->left == tree->nil);
}
unsigned int rb_size(struct rb_tree *tree)
{
return tree->size;
}
struct rb_node *rb_begin(struct rb_tree *tree)
{
struct rb_node *x = tree->root->left;
while (x->left != tree->nil)
x = x->left;
return x;
}
struct rb_node *rb_end(struct rb_tree *tree)
{
return tree->nil;
}
static void rb_rotate_left(struct rb_tree *tree, struct rb_node *x)
{
struct rb_node *y, *nil = tree->nil;
y = x->right;
x->right = y->left;
if (y->left != nil) y->left->parent = x;
y->parent = x->parent;
if (x == x->parent->left) {
x->parent->left = y;
}
else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
assert(!tree->nil->red);
}
static void rb_rotate_right(struct rb_tree *tree, struct rb_node *y)
{
struct rb_node *x, *nil = tree->nil;
x = y->left;
y->left = x->right;
if (nil != x->right) x->right->parent = y;
x->parent = y->parent;
if (y == y->parent->left) {
y->parent->left = x;
}
else {
y->parent->right = x;
}
x->right=y;
y->parent=x;
assert(!tree->nil->red);
}
static void rb_insert_helper(struct rb_tree *tree, struct rb_node *z)
{
struct rb_node *x, *y, *nil = tree->nil;
z->left = z->right = nil;
y = tree->root;
x = tree->root->left;
while (x != nil)
{
y = x;
if (tree->compare_keys(x->key, z->key) > 0) {
x = x->left;
}
else {
x = x->right;
}
}
z->parent = y;
if ( (y == tree->root) ||
(tree->compare_keys(y->key, z->key) > 0) ) {
y->left = z;
}
else {
y->right = z;
}
assert(!tree->nil->red);
}
struct rb_node *rb_insert(struct rb_tree *tree, void *key, void *value)
{
struct rb_node *x, *y, *newnode;
x = (struct rb_node*)malloc(sizeof(struct rb_node));
x->key = key;
x->value = value;
rb_insert_helper(tree, x);
newnode = x;
x->red = 1;
while (x->parent->red)
{
if (x->parent == x->parent->parent->left)
{
y = x->parent->parent->right;
if (y->red)
{
x->parent->red = 0;
y->red = 0;
x->parent->parent->red = 1;
x = x->parent->parent;
}
else
{
if (x == x->parent->right) {
x = x->parent;
rb_rotate_left(tree, x);
}
x->parent->red = 0;
x->parent->parent->red = 1;
rb_rotate_right(tree, x->parent->parent);
}
}
else
{
y = x->parent->parent->left;
if (y->red)
{
x->parent->red = 0;
y->red = 0;
x->parent->parent->red = 1;
x = x->parent->parent;
}
else
{
if (x == x->parent->left) {
x = x->parent;
rb_rotate_right(tree, x);
}
x->parent->red = 0;
x->parent->parent->red = 1;
rb_rotate_left(tree, x->parent->parent);
}
}
}
tree->root->left->red = 0;
++tree->size;
#ifdef RBTREE_VERIFY
assert(rb_verify(tree));
#endif
return newnode;
}
struct rb_node *rb_successor(struct rb_tree *tree, struct rb_node *x)
{
struct rb_node *y, *nil = tree->nil;
struct rb_node *root = tree->root;
if (nil != (y = x->right))
{
while (y->left != nil) {
y = y->left;
}
return y;
}
else
{
y = x->parent;
while (x == y->right) {
x = y;
y = y->parent;
}
if (y == root) return nil;
return y;
}
}
struct rb_node *rb_predecessor(struct rb_tree *tree, struct rb_node *x)
{
struct rb_node *y, *nil = tree->nil;
struct rb_node *root = tree->root;
if (nil != (y = x->left))
{
while (y->right != nil) {
y = y->right;
}
return y;
}
else
{
y = x->parent;
while (x == y->left) {
if (y == root) return nil;
x = y;
y = y->parent;
}
return y;
}
}
static void rb_destroy_helper(struct rb_tree *tree, struct rb_node *x)
{
if (x != tree->nil)
{
rb_destroy_helper(tree, x->left);
rb_destroy_helper(tree, x->right);
tree->destroy_key(x->key);
tree->destroy_value(x->value);
free(x);
}
}
void rb_destroy(struct rb_tree *tree)
{
rb_destroy_helper(tree, tree->root->left);
free(tree->root);
free(tree->nil);
free(tree);
}
static void rb_print_inorder(struct rb_tree *tree, struct rb_node *x)
{
struct rb_node *nil = tree->nil;
struct rb_node *root = tree->root;
if (x != tree->nil)
{
rb_print_inorder(tree, x->left);
printf("value=");
tree->print_value(x->value);
printf(" key=");
tree->print_key(x->key);
printf(" l->key=");
if (x->left == nil) printf("NULL");
else tree->print_key(x->left->key);
printf(" r->key=");
if (x->right == nil) printf("NULL");
else tree->print_key(x->right->key);
printf(" p->key=");
if (x->parent == root) printf("NULL");
else tree->print_key(x->parent->key);
printf(" red=%i\n", x->red);
rb_print_inorder(tree, x->right);
}
}
void rb_print(struct rb_tree *tree)
{
assert(tree->print_key != NULL);
assert(tree->print_value != NULL);
rb_print_inorder(tree, tree->root->left);
}
struct rb_node *rb_find(struct rb_tree *tree, const void *key)
{
struct rb_node *x = tree->root->left;
struct rb_node *nil = tree->nil;
int cmpval;
if (x == nil) return NULL;
cmpval = tree->compare_keys(x->key, key);
while (cmpval != 0)
{
if (cmpval > 0) {
x = x->left;
}
else {
x = x->right;
}
if (x == nil) return NULL;
cmpval = tree->compare_keys(x->key, key);
}
while (x->left != nil && tree->compare_keys(key, x->left->key) == 0) {
x = x->left;
}
return x;
}
static void rb_delete_fixup(struct rb_tree *tree, struct rb_node *x)
{
struct rb_node *root = tree->root->left;
struct rb_node *w;
while ( (!x->red) && (root != x) )
{
if (x == x->parent->left)
{
w = x->parent->right;
if (w->red) {
w->red = 0;
x->parent->red = 1;
rb_rotate_left(tree, x->parent);
w = x->parent->right;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red = 1;
x = x->parent;
}
else {
if (!w->right->red) {
w->left->red = 0;
w->red = 1;
rb_rotate_right(tree, w);
w = x->parent->right;
}
w->red = x->parent->red;
x->parent->red = 0;
w->right->red = 0;
rb_rotate_left(tree, x->parent);
x = root;
}
}
else
{
w = x->parent->left;
if (w->red) {
w->red = 0;
x->parent->red = 1;
rb_rotate_right(tree, x->parent);
w = x->parent->left;
}
if ( (!w->right->red) && (!w->left->red) ) {
w->red = 1;
x = x->parent;
}
else {
if (!w->left->red) {
w->right->red = 0;
w->red = 1;
rb_rotate_left(tree, w);
w = x->parent->left;
}
w->red = x->parent->red;
x->parent->red = 0;
w->left->red = 0;
rb_rotate_right(tree, x->parent);
x = root;
}
}
}
x->red = 0;
assert(!tree->nil->red);
}
void rb_delete(struct rb_tree *tree, struct rb_node *z)
{
struct rb_node *x, *y, *nil = tree->nil;
struct rb_node *root = tree->root;
y = ((z->left == nil) || (z->right == nil)) ? z : rb_successor(tree, z);
x = (y->left == nil) ? y->right : y->left;
if (root == (x->parent = y->parent)) {
root->left = x;
}
else {
if (y == y->parent->left) {
y->parent->left = x;
}
else {
y->parent->right = x;
}
}
if (y != z)
{
assert( (y!=tree->nil) );
if (!(y->red)) rb_delete_fixup(tree, x);
tree->destroy_key(z->key);
tree->destroy_value(z->value);
y->left = z->left;
y->right = z->right;
y->parent = z->parent;
y->red = z->red;
z->left->parent = z->right->parent = y;
if (z == z->parent->left) {
z->parent->left = y;
}
else {
z->parent->right = y;
}
free(z);
}
else
{
tree->destroy_key(y->key);
tree->destroy_value(y->value);
if (!(y->red)) rb_delete_fixup(tree, x);
free(y);
}
--tree->size;
#ifdef RBTREE_VERIFY
assert(rb_verify(tree));
#endif
}
static int rb_verify_helper(struct rb_tree *tree, struct rb_node *z, int blacks, int *blackmatch, unsigned int *count)
{
if (z->red)
{
if (z->left->red) return 0;
if (z->right->red) return 0;
}
if (!z->red) ++blacks;
if (++(*count) > tree->size)
return 0;
if (z->left != tree->nil) {
if (!rb_verify_helper(tree, z->left, blacks, blackmatch, count))
return 0;
}
else {
if (*blackmatch < 0)
*blackmatch = blacks;
else if (*blackmatch != blacks)
return 0;
}
if (z->right != tree->nil) {
if (!rb_verify_helper(tree, z->right, blacks, blackmatch, count))
return 0;
}
else {
if (*blackmatch < 0)
*blackmatch = blacks;
else if (*blackmatch != blacks)
return 0;
}
return 1;
}
int rb_verify(struct rb_tree *tree)
{
int blackmatch = -1;
unsigned int count = 0;
if (tree->nil->red) return 0;
if (tree->root->left->red) return 0;
if (tree->root->left != tree->nil) {
if (!rb_verify_helper(tree, tree->root->left, 0, &blackmatch, &count))
return 0;
}
if (count != tree->size) return 0;
return 1;
}