Commit f6e96254 authored by Chris Müller's avatar Chris Müller

lib: use crystal name_conventation for red-black trees.

lib: red-black nodes can store a data pointer now.
parent b13a7ef3
...@@ -22,12 +22,12 @@ ...@@ -22,12 +22,12 @@
#include "red_black_tree.h" #include "red_black_tree.h"
struct RBTree* struct CryRbTree*
rb_tree_new(cry_ordering_funptr compare) cry_rbtree_new(cry_ordering_funptr compare)
{ {
assert(compare != 0); assert(compare != 0);
struct RBTree* tree = cry_malloc(struct RBTree); struct CryRbTree* tree = cry_malloc(struct CryRbTree);
tree->root = 0; tree->root = 0;
tree->compare = compare; tree->compare = compare;
tree->nodes = 0; tree->nodes = 0;
...@@ -36,15 +36,16 @@ rb_tree_new(cry_ordering_funptr compare) ...@@ -36,15 +36,16 @@ rb_tree_new(cry_ordering_funptr compare)
} }
struct RBNode* struct CryRbNode*
rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer entry) cry_rbnode_new(enum CryRbNodeColor color, struct CryRbNode* parent, const_pointer entry, const_pointer data)
{ {
assert(entry != 0); assert(entry != 0);
struct RBNode* node = cry_malloc(struct RBNode); struct CryRbNode* node = cry_malloc(struct CryRbNode);
node->color = color; node->color = color;
node->parent = parent; node->parent = parent;
node->entry = entry; node->entry = entry;
node->data = data;
node->left = 0; node->left = 0;
node->right = 0; node->right = 0;
...@@ -52,24 +53,24 @@ rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer entry) ...@@ -52,24 +53,24 @@ rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer entry)
} }
static rb_subtree_free(struct RBNode* node, cry_free_funptr fun) static cry_rbsubtree_free(struct CryRbNode* node, cry_free_funptr fun_entry, cry_free_funptr fun_data)
{ {
if(node == 0) if(node == 0)
return; return;
rb_subtree_free(node->left, fun); cry_rbsubtree_free(node->left, fun_entry, fun_data);
rb_subtree_free(node->right, fun); cry_rbsubtree_free(node->right, fun_entry, fun_data);
rb_node_free(node, fun); cry_rbnode_free(node, fun_entry, fun_data);
} }
void void
rb_tree_clear(struct RBTree* tree, cry_free_funptr fun) cry_rbtree_clear(struct CryRbTree* tree, cry_free_funptr fun_entry, cry_free_funptr fun_data)
{ {
assert(tree != 0); assert(tree != 0);
rb_subtree_free(tree->root, fun); cry_rbsubtree_free(tree->root, fun_entry, fun_data);
tree->root = 0; tree->root = 0;
tree->nodes = 0; tree->nodes = 0;
...@@ -77,24 +78,27 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr fun) ...@@ -77,24 +78,27 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr fun)
void void
rb_node_free(struct RBNode* node, cry_free_funptr free_entry) cry_rbnode_free(struct CryRbNode* node, cry_free_funptr fun_entry, cry_free_funptr fun_data)
{ {
assert(node != 0); assert(node != 0);
if(free_entry != 0) if(fun_entry != 0)
free_entry(cry_cast(pointer, node->entry)); fun_entry(cry_cast(pointer, node->entry));
if(fun_data != 0)
fun_data(cry_cast(pointer, node->data));
cry_free(node); cry_free(node);
} }
struct RBNode* struct CryRbNode*
rb_tree_lookup(struct RBTree* tree, const_pointer entry) cry_rbtree_lookup(struct CryRbTree* tree, const_pointer entry)
{ {
assert(tree != 0 && entry != 0); assert(tree != 0 && entry != 0);
struct RBNode* node = tree->root; struct CryRbNode* node = tree->root;
while(node != 0) { while(node != 0) {
int result = tree->compare(entry, node->entry); int result = tree->compare(entry, node->entry);
...@@ -112,13 +116,13 @@ rb_tree_lookup(struct RBTree* tree, const_pointer entry) ...@@ -112,13 +116,13 @@ rb_tree_lookup(struct RBTree* tree, const_pointer entry)
static struct RBNode* static struct CryRbNode*
rb_node_rotate_left(struct RBNode* node) cry_rbnode_rotate_left(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* parent = node->parent; struct CryRbNode* parent = node->parent;
struct RBNode* right = node->right; struct CryRbNode* right = node->right;
// switch right-node and its parent in a left-in-order rotation // switch right-node and its parent in a left-in-order rotation
node->right = right->left; node->right = right->left;
...@@ -141,13 +145,13 @@ rb_node_rotate_left(struct RBNode* node) ...@@ -141,13 +145,13 @@ rb_node_rotate_left(struct RBNode* node)
} }
static struct RBNode* static struct CryRbNode*
rb_node_rotate_right(struct RBNode* node) cry_rbnode_rotate_right(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* parent = node->parent; struct CryRbNode* parent = node->parent;
struct RBNode* left = node->left; struct CryRbNode* left = node->left;
// switch left-node and its parent in a right-in-order rotation // switch left-node and its parent in a right-in-order rotation
node->left = left->right; node->left = left->right;
...@@ -171,26 +175,26 @@ rb_node_rotate_right(struct RBNode* node) ...@@ -171,26 +175,26 @@ rb_node_rotate_right(struct RBNode* node)
static struct RBNode* static struct CryRbNode*
rb_trinode_restructering(struct RBNode* node) cry_rbtrinode_restructering(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* root = RB_GRAND_PARENT(node); struct CryRbNode* root = RB_GRAND_PARENT(node);
if(root->left == RB_PARENT(node)) { if(root->left == RB_PARENT(node)) {
if(RB_PARENT(node)->left == node) if(RB_PARENT(node)->left == node)
root = rb_node_rotate_right(root); root = cry_rbnode_rotate_right(root);
else { else {
rb_node_rotate_left(RB_PARENT(node)); cry_rbnode_rotate_left(RB_PARENT(node));
root = rb_node_rotate_right(root); root = cry_rbnode_rotate_right(root);
} }
} else { } else {
if(RB_PARENT(node)->right == node) if(RB_PARENT(node)->right == node)
root = rb_node_rotate_left(root); root = cry_rbnode_rotate_left(root);
else { else {
rb_node_rotate_right(RB_PARENT(node)); cry_rbnode_rotate_right(RB_PARENT(node));
root = rb_node_rotate_left(root); root = cry_rbnode_rotate_left(root);
} }
} }
...@@ -199,7 +203,7 @@ rb_trinode_restructering(struct RBNode* node) ...@@ -199,7 +203,7 @@ rb_trinode_restructering(struct RBNode* node)
static void static void
rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z) cry_rbremedy_double_red(struct CryRbTree* tree, struct CryRbNode* node_z)
{ {
assert(tree != 0 && node_z != 0); assert(tree != 0 && node_z != 0);
...@@ -210,7 +214,7 @@ rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z) ...@@ -210,7 +214,7 @@ rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z)
if(RB_GRAND_PARENT(node_z)->left == 0 || RB_GRAND_PARENT(node_z)->right == 0 || RB_GRAND_PARENT(node_z)->left->color == BLACK || RB_GRAND_PARENT(node_z)->right->color == BLACK) { if(RB_GRAND_PARENT(node_z)->left == 0 || RB_GRAND_PARENT(node_z)->right == 0 || RB_GRAND_PARENT(node_z)->left->color == BLACK || RB_GRAND_PARENT(node_z)->right->color == BLACK) {
// trinode restructering with single/multiple left- and right rotations // trinode restructering with single/multiple left- and right rotations
struct RBNode* node_v = rb_trinode_restructering(node_z); struct CryRbNode* node_v = cry_rbtrinode_restructering(node_z);
node_v->color = BLACK; node_v->color = BLACK;
node_v->left->color = RED; node_v->left->color = RED;
...@@ -229,23 +233,23 @@ rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z) ...@@ -229,23 +233,23 @@ rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z)
return; return;
RB_GRAND_PARENT(node_z)->color = RED; RB_GRAND_PARENT(node_z)->color = RED;
rb_remedy_double_red(tree, RB_GRAND_PARENT(node_z)); cry_rbremedy_double_red(tree, RB_GRAND_PARENT(node_z));
} }
} }
static void static void
rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode* node_r) cry_rbremedy_double_black(struct CryRbTree* tree, struct CryRbNode* node_x, struct CryRbNode* node_r)
{ {
assert(node_x != 0); assert(node_x != 0);
struct RBNode* sibling = (node_x->left == node_r) ? node_x->right : node_x->left; struct CryRbNode* sibling = (node_x->left == node_r) ? node_x->right : node_x->left;
struct RBNode* child = 0; struct CryRbNode* child = 0;
if(sibling == 0) if(sibling == 0)
return; return;
enum RBNodeColor parent_color = node_x->color; enum CryRbNodeColor parent_color = node_x->color;
if(sibling->color == BLACK) { if(sibling->color == BLACK) {
// get red child of siblings if available // get red child of siblings if available
...@@ -256,7 +260,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode ...@@ -256,7 +260,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
if(child != 0) { if(child != 0) {
// Case 1: Restructering of siblings red child // Case 1: Restructering of siblings red child
child = rb_trinode_restructering(child); child = cry_rbtrinode_restructering(child);
child->color = parent_color; child->color = parent_color;
if(node_r != 0) if(node_r != 0)
...@@ -275,7 +279,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode ...@@ -275,7 +279,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
if(node_x->color == RED) if(node_x->color == RED)
node_x->color = BLACK; node_x->color = BLACK;
else if(node_x->parent != 0) { else if(node_x->parent != 0) {
rb_remedy_double_black(tree, RB_PARENT(node_x), node_x); cry_rbremedy_double_black(tree, RB_PARENT(node_x), node_x);
} }
} }
...@@ -287,7 +291,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode ...@@ -287,7 +291,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
child = sibling->left; child = sibling->left;
if(child != 0) { if(child != 0) {
child = rb_trinode_restructering(child); child = cry_rbtrinode_restructering(child);
sibling->color = BLACK; sibling->color = BLACK;
node_x->color = RED; node_x->color = RED;
...@@ -295,22 +299,22 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode ...@@ -295,22 +299,22 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
child = child->parent; child = child->parent;
tree->root = child; tree->root = child;
rb_remedy_double_black(tree, node_x, node_r); cry_rbremedy_double_black(tree, node_x, node_r);
} }
} }
} }
struct RBNode* struct CryRbNode*
rb_tree_insert(struct RBTree* tree, const_pointer entry) cry_rbtree_insert(struct CryRbTree* tree, const_pointer entry, const_pointer data)
{ {
assert(tree != 0 && entry != 0); assert(tree != 0 && entry != 0);
struct RBNode* node = tree->root; struct CryRbNode* node = tree->root;
struct RBNode* current_node = 0; struct CryRbNode* current_node = 0;
if(node == 0) { if(node == 0) {
tree->root = rb_node_new(BLACK, 0, entry); tree->root = cry_rbnode_new(BLACK, 0, entry, data);
tree->nodes += 1; tree->nodes += 1;
return tree->root; return tree->root;
} }
...@@ -321,12 +325,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry) ...@@ -321,12 +325,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
if(result < 0) { if(result < 0) {
if(node->left == 0) if(node->left == 0)
current_node = node->left = rb_node_new(RED, node, entry); current_node = node->left = cry_rbnode_new(RED, node, entry, data);
else else
node = node->left; node = node->left;
} else if(result > 0) { } else if(result > 0) {
if(node->right == 0) if(node->right == 0)
current_node = node->right = rb_node_new(RED, node, entry); current_node = node->right = cry_rbnode_new(RED, node, entry, data);
else else
node = node->right; node = node->right;
} else { } else {
...@@ -335,7 +339,7 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry) ...@@ -335,7 +339,7 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
} }
// repair binary search tree based on red-black tree properties // repair binary search tree based on red-black tree properties
rb_remedy_double_red(tree, current_node); cry_rbremedy_double_red(tree, current_node);
tree->nodes += 1; tree->nodes += 1;
...@@ -343,12 +347,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry) ...@@ -343,12 +347,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
} }
static struct RBNode* static struct CryRbNode*
rb_remove_external_node(struct RBNode* node) cry_rbremove_external_node(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* child = (node->left == 0) ? node->right : node->left; struct CryRbNode* child = (node->left == 0) ? node->right : node->left;
if(RB_PARENT(node) != 0 && RB_PARENT(node)->left == node) if(RB_PARENT(node) != 0 && RB_PARENT(node)->left == node)
RB_PARENT(node)->left = child; RB_PARENT(node)->left = child;
...@@ -362,17 +366,17 @@ rb_remove_external_node(struct RBNode* node) ...@@ -362,17 +366,17 @@ rb_remove_external_node(struct RBNode* node)
} }
struct RBNode* struct CryRbNode*
rb_tree_remove(struct RBTree* tree, const_pointer entry) cry_rbtree_remove(struct CryRbTree* tree, const_pointer entry)
{ {
assert(tree != 0 && entry != 0); assert(tree != 0 && entry != 0);
struct RBNode* node = 0; struct CryRbNode* node = 0;
struct RBNode* current_node = 0; struct CryRbNode* current_node = 0;
struct RBNode* data_node = 0; struct CryRbNode* data_node = 0;
// search for a node with the same entry within the binary tree // search for a node with the same entry within the binary tree
current_node = rb_tree_lookup(tree, entry); current_node = cry_rbtree_lookup(tree, entry);
if(current_node == 0) if(current_node == 0)
return current_node; return current_node;
...@@ -385,15 +389,18 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry) ...@@ -385,15 +389,18 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry)
// swap its entry information // swap its entry information
const_pointer tmp_entry = node->entry; const_pointer tmp_entry = node->entry;
const_pointer tmp_data = node->data;
node->entry = current_node->entry; node->entry = current_node->entry;
node->data = current_node->data;
current_node->entry = tmp_entry; current_node->entry = tmp_entry;
current_node->data = tmp_data;
data_node = node; data_node = node;
node = rb_remove_external_node(node); node = cry_rbremove_external_node(node);
} else { } else {
// Remove internal node and replace it by its single subtree (Easy case) // Remove internal node and replace it by its single subtree (Easy case)
data_node = current_node; data_node = current_node;
node = rb_remove_external_node(current_node); node = cry_rbremove_external_node(current_node);
} }
// Node removed, now correct tree for red_black_tree properties // Node removed, now correct tree for red_black_tree properties
...@@ -404,7 +411,7 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry) ...@@ -404,7 +411,7 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry)
} else if(node != 0 && (node->color == RED || RB_PARENT(data_node)->color == RED)) { } else if(node != 0 && (node->color == RED || RB_PARENT(data_node)->color == RED)) {
node->color = BLACK; node->color = BLACK;
} else { } else {
rb_remedy_double_black(tree, RB_PARENT(data_node), node); cry_rbremedy_double_black(tree, RB_PARENT(data_node), node);
} }
tree->nodes -= 1; tree->nodes -= 1;
...@@ -413,15 +420,15 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry) ...@@ -413,15 +420,15 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry)
} }
struct RBNode* struct CryRbNode*
rb_node_first(struct RBTree* tree) cry_rbnode_first(struct CryRbTree* tree)
{ {
assert(tree != 0); assert(tree != 0);
if(tree->root == 0) if(tree->root == 0)
return 0; return 0;
struct RBNode* node = tree->root; struct CryRbNode* node = tree->root;
while(node->left != 0) { while(node->left != 0) {
node = node->left; node = node->left;
...@@ -431,15 +438,15 @@ rb_node_first(struct RBTree* tree) ...@@ -431,15 +438,15 @@ rb_node_first(struct RBTree* tree)
} }
struct RBNode* struct CryRbNode*
rb_node_last(struct RBTree* tree) cry_rbnode_last(struct CryRbTree* tree)
{ {
assert(tree != 0); assert(tree != 0);
if(tree->root == 0) if(tree->root == 0)
return 0; return 0;
struct RBNode* node = tree->root; struct CryRbNode* node = tree->root;
while(node->right != 0) { while(node->right != 0) {
node = node->right; node = node->right;
...@@ -450,12 +457,12 @@ rb_node_last(struct RBTree* tree) ...@@ -450,12 +457,12 @@ rb_node_last(struct RBTree* tree)
struct RBNode* struct CryRbNode*
rb_node_next(struct RBNode* node) cry_rbnode_next(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* tmp = 0; struct CryRbNode* tmp = 0;
if(node->right != 0) { if(node->right != 0) {
tmp = node->right; tmp = node->right;
...@@ -477,12 +484,12 @@ rb_node_next(struct RBNode* node) ...@@ -477,12 +484,12 @@ rb_node_next(struct RBNode* node)
} }
struct RBNode* struct CryRbNode*
rb_node_prev(struct RBNode* node) cry_rbnode_prev(struct CryRbNode* node)
{ {
assert(node != 0); assert(node != 0);
struct RBNode* tmp = 0; struct CryRbNode* tmp = 0;
if(node->left != 0) { if(node->left != 0) {
tmp = node->left; tmp = node->left;
......
...@@ -21,19 +21,20 @@ ...@@ -21,19 +21,20 @@
#include "structures.h" #include "structures.h"
enum RBNodeColor { RED, BLACK }; enum CryRbNodeColor { RED, BLACK };
struct RBNode { struct CryRbNode {
const_pointer entry; const_pointer entry;
enum RBNodeColor color; const_pointer data;