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 @@
#include "red_black_tree.h"
struct RBTree*
rb_tree_new(cry_ordering_funptr compare)
struct CryRbTree*
cry_rbtree_new(cry_ordering_funptr compare)
{
assert(compare != 0);
struct RBTree* tree = cry_malloc(struct RBTree);
struct CryRbTree* tree = cry_malloc(struct CryRbTree);
tree->root = 0;
tree->compare = compare;
tree->nodes = 0;
......@@ -36,15 +36,16 @@ rb_tree_new(cry_ordering_funptr compare)
}
struct RBNode*
rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer entry)
struct CryRbNode*
cry_rbnode_new(enum CryRbNodeColor color, struct CryRbNode* parent, const_pointer entry, const_pointer data)
{
assert(entry != 0);
struct RBNode* node = cry_malloc(struct RBNode);
struct CryRbNode* node = cry_malloc(struct CryRbNode);
node->color = color;
node->parent = parent;
node->entry = entry;
node->data = data;
node->left = 0;
node->right = 0;
......@@ -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)
return;
rb_subtree_free(node->left, fun);
rb_subtree_free(node->right, fun);
cry_rbsubtree_free(node->left, fun_entry, fun_data);
cry_rbsubtree_free(node->right, fun_entry, fun_data);
rb_node_free(node, fun);
cry_rbnode_free(node, fun_entry, fun_data);
}
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);
rb_subtree_free(tree->root, fun);
cry_rbsubtree_free(tree->root, fun_entry, fun_data);
tree->root = 0;
tree->nodes = 0;
......@@ -77,24 +78,27 @@ rb_tree_clear(struct RBTree* tree, cry_free_funptr fun)
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);
if(free_entry != 0)
free_entry(cry_cast(pointer, node->entry));
if(fun_entry != 0)
fun_entry(cry_cast(pointer, node->entry));
if(fun_data != 0)
fun_data(cry_cast(pointer, node->data));
cry_free(node);
}
struct RBNode*
rb_tree_lookup(struct RBTree* tree, const_pointer entry)
struct CryRbNode*
cry_rbtree_lookup(struct CryRbTree* tree, const_pointer entry)
{
assert(tree != 0 && entry != 0);
struct RBNode* node = tree->root;
struct CryRbNode* node = tree->root;
while(node != 0) {
int result = tree->compare(entry, node->entry);
......@@ -112,13 +116,13 @@ rb_tree_lookup(struct RBTree* tree, const_pointer entry)
static struct RBNode*
rb_node_rotate_left(struct RBNode* node)
static struct CryRbNode*
cry_rbnode_rotate_left(struct CryRbNode* node)
{
assert(node != 0);
struct RBNode* parent = node->parent;
struct RBNode* right = node->right;
struct CryRbNode* parent = node->parent;
struct CryRbNode* right = node->right;
// switch right-node and its parent in a left-in-order rotation
node->right = right->left;
......@@ -141,13 +145,13 @@ rb_node_rotate_left(struct RBNode* node)
}
static struct RBNode*
rb_node_rotate_right(struct RBNode* node)
static struct CryRbNode*
cry_rbnode_rotate_right(struct CryRbNode* node)
{
assert(node != 0);
struct RBNode* parent = node->parent;
struct RBNode* left = node->left;
struct CryRbNode* parent = node->parent;
struct CryRbNode* left = node->left;
// switch left-node and its parent in a right-in-order rotation
node->left = left->right;
......@@ -171,26 +175,26 @@ rb_node_rotate_right(struct RBNode* node)
static struct RBNode*
rb_trinode_restructering(struct RBNode* node)
static struct CryRbNode*
cry_rbtrinode_restructering(struct CryRbNode* node)
{
assert(node != 0);
struct RBNode* root = RB_GRAND_PARENT(node);
struct CryRbNode* root = RB_GRAND_PARENT(node);
if(root->left == RB_PARENT(node)) {
if(RB_PARENT(node)->left == node)
root = rb_node_rotate_right(root);
root = cry_rbnode_rotate_right(root);
else {
rb_node_rotate_left(RB_PARENT(node));
root = rb_node_rotate_right(root);
cry_rbnode_rotate_left(RB_PARENT(node));
root = cry_rbnode_rotate_right(root);
}
} else {
if(RB_PARENT(node)->right == node)
root = rb_node_rotate_left(root);
root = cry_rbnode_rotate_left(root);
else {
rb_node_rotate_right(RB_PARENT(node));
root = rb_node_rotate_left(root);
cry_rbnode_rotate_right(RB_PARENT(node));
root = cry_rbnode_rotate_left(root);
}
}
......@@ -199,7 +203,7 @@ rb_trinode_restructering(struct RBNode* node)
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);
......@@ -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) {
// 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->left->color = RED;
......@@ -229,23 +233,23 @@ rb_remedy_double_red(struct RBTree* tree, struct RBNode* node_z)
return;
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
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);
struct RBNode* sibling = (node_x->left == node_r) ? node_x->right : node_x->left;
struct RBNode* child = 0;
struct CryRbNode* sibling = (node_x->left == node_r) ? node_x->right : node_x->left;
struct CryRbNode* child = 0;
if(sibling == 0)
return;
enum RBNodeColor parent_color = node_x->color;
enum CryRbNodeColor parent_color = node_x->color;
if(sibling->color == BLACK) {
// get red child of siblings if available
......@@ -256,7 +260,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
if(child != 0) {
// Case 1: Restructering of siblings red child
child = rb_trinode_restructering(child);
child = cry_rbtrinode_restructering(child);
child->color = parent_color;
if(node_r != 0)
......@@ -275,7 +279,7 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
if(node_x->color == RED)
node_x->color = BLACK;
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
child = sibling->left;
if(child != 0) {
child = rb_trinode_restructering(child);
child = cry_rbtrinode_restructering(child);
sibling->color = BLACK;
node_x->color = RED;
......@@ -295,22 +299,22 @@ rb_remedy_double_black(struct RBTree* tree, struct RBNode* node_x, struct RBNode
child = child->parent;
tree->root = child;
rb_remedy_double_black(tree, node_x, node_r);
cry_rbremedy_double_black(tree, node_x, node_r);
}
}
}
struct RBNode*
rb_tree_insert(struct RBTree* tree, const_pointer entry)
struct CryRbNode*
cry_rbtree_insert(struct CryRbTree* tree, const_pointer entry, const_pointer data)
{
assert(tree != 0 && entry != 0);
struct RBNode* node = tree->root;
struct RBNode* current_node = 0;
struct CryRbNode* node = tree->root;
struct CryRbNode* current_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;
return tree->root;
}
......@@ -321,12 +325,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
if(result < 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
node = node->left;
} else if(result > 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
node = node->right;
} else {
......@@ -335,7 +339,7 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
}
// 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;
......@@ -343,12 +347,12 @@ rb_tree_insert(struct RBTree* tree, const_pointer entry)
}
static struct RBNode*
rb_remove_external_node(struct RBNode* node)
static struct CryRbNode*
cry_rbremove_external_node(struct CryRbNode* node)
{
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)
RB_PARENT(node)->left = child;
......@@ -362,17 +366,17 @@ rb_remove_external_node(struct RBNode* node)
}
struct RBNode*
rb_tree_remove(struct RBTree* tree, const_pointer entry)
struct CryRbNode*
cry_rbtree_remove(struct CryRbTree* tree, const_pointer entry)
{
assert(tree != 0 && entry != 0);
struct RBNode* node = 0;
struct RBNode* current_node = 0;
struct RBNode* data_node = 0;
struct CryRbNode* node = 0;
struct CryRbNode* current_node = 0;
struct CryRbNode* data_node = 0;
// 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)
return current_node;
......@@ -385,15 +389,18 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry)
// swap its entry information
const_pointer tmp_entry = node->entry;
const_pointer tmp_data = node->data;
node->entry = current_node->entry;
node->data = current_node->data;
current_node->entry = tmp_entry;
current_node->data = tmp_data;
data_node = node;
node = rb_remove_external_node(node);
node = cry_rbremove_external_node(node);
} else {
// Remove internal node and replace it by its single subtree (Easy case)
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
......@@ -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)) {
node->color = BLACK;
} else {
rb_remedy_double_black(tree, RB_PARENT(data_node), node);
cry_rbremedy_double_black(tree, RB_PARENT(data_node), node);
}
tree->nodes -= 1;
......@@ -413,15 +420,15 @@ rb_tree_remove(struct RBTree* tree, const_pointer entry)
}
struct RBNode*
rb_node_first(struct RBTree* tree)
struct CryRbNode*
cry_rbnode_first(struct CryRbTree* tree)
{
assert(tree != 0);
if(tree->root == 0)
return 0;
struct RBNode* node = tree->root;
struct CryRbNode* node = tree->root;
while(node->left != 0) {
node = node->left;
......@@ -431,15 +438,15 @@ rb_node_first(struct RBTree* tree)
}
struct RBNode*
rb_node_last(struct RBTree* tree)
struct CryRbNode*
cry_rbnode_last(struct CryRbTree* tree)
{
assert(tree != 0);
if(tree->root == 0)
return 0;
struct RBNode* node = tree->root;
struct CryRbNode* node = tree->root;
while(node->right != 0) {
node = node->right;
......@@ -450,12 +457,12 @@ rb_node_last(struct RBTree* tree)
struct RBNode*
rb_node_next(struct RBNode* node)
struct CryRbNode*
cry_rbnode_next(struct CryRbNode* node)
{
assert(node != 0);
struct RBNode* tmp = 0;
struct CryRbNode* tmp = 0;
if(node->right != 0) {
tmp = node->right;
......@@ -477,12 +484,12 @@ rb_node_next(struct RBNode* node)
}
struct RBNode*
rb_node_prev(struct RBNode* node)
struct CryRbNode*
cry_rbnode_prev(struct CryRbNode* node)
{
assert(node != 0);
struct RBNode* tmp = 0;
struct CryRbNode* tmp = 0;
if(node->left != 0) {
tmp = node->left;
......
......@@ -21,19 +21,20 @@
#include "structures.h"
enum RBNodeColor { RED, BLACK };
enum CryRbNodeColor { RED, BLACK };
struct RBNode {
struct CryRbNode {
const_pointer entry;
enum RBNodeColor color;
struct RBNode* parent;
struct RBNode* left;
struct RBNode* right;
const_pointer data;
enum CryRbNodeColor color;
struct CryRbNode* parent;
struct CryRbNode* left;
struct CryRbNode* right;
};
struct RBTree {
struct RBNode* root;
struct CryRbTree {
struct CryRbNode* root;
cry_ordering_funptr compare;
size_t nodes;
};
......@@ -43,21 +44,21 @@ struct RBTree {
#define RB_GRAND_PARENT(node) node->parent->parent
struct RBTree* rb_tree_new(cry_ordering_funptr compare);
void rb_tree_clear(struct RBTree* tree, cry_free_funptr fun);
struct CryRbTree* cry_rbtree_new(cry_ordering_funptr compare);
void cry_rbtree_clear(struct CryRbTree* tree, cry_free_funptr fun_entry, cry_free_funptr fun_data);
struct RBNode* rb_tree_lookup(struct RBTree* tree, const_pointer entry);
struct RBNode* rb_tree_insert(struct RBTree* tree, const_pointer entry);
struct RBNode* rb_tree_remove(struct RBTree* tree, const_pointer entry);
struct CryRbNode* cry_rbtree_lookup(struct CryRbTree* tree, const_pointer entry);
struct CryRbNode* cry_rbtree_insert(struct CryRbTree* tree, const_pointer entry, const_pointer data);
struct CryRbNode* cry_rbtree_remove(struct CryRbTree* tree, const_pointer entry);
struct RBNode* rb_node_first(struct RBTree* tree);
struct RBNode* rb_node_last(struct RBTree* tree);
struct CryRbNode* cry_rbnode_first(struct CryRbTree* tree);
struct CryRbNode* cry_rbnode_last(struct CryRbTree* tree);
struct RBNode* rb_node_next(struct RBNode* node);
struct RBNode* rb_node_prev(struct RBNode* node);
struct CryRbNode* cry_rbnode_next(struct CryRbNode* node);
struct CryRbNode* cry_rbnode_prev(struct CryRbNode* node);
struct RBNode* rb_node_new(enum RBNodeColor color, struct RBNode* parent, const_pointer entry);
void rb_node_free(struct RBNode* node, cry_free_funptr fun);
struct CryRbNode* cry_rbnode_new(enum CryRbNodeColor color, struct CryRbNode* parent, const_pointer entry, const_pointer data);
void cry_rbnode_free(struct CryRbNode* node, cry_free_funptr fun_entry, cry_free_funptr fun_data);
......
......@@ -7,12 +7,12 @@
static void
test_red_black_tree_initialization(const_pointer data)
{
struct RBTree* tree = rb_tree_new(cry_int_compare);
struct CryRbTree* tree = cry_rbtree_new(cry_int_compare);
assert(tree->nodes == 0);
assert(rb_tree_lookup(tree, "unknown_key") == 0);
assert(cry_rbtree_lookup(tree, "unknown_key") == 0);
rb_tree_clear(tree, 0);
cry_rbtree_clear(tree, 0, 0);
cry_free(tree);
}
......@@ -20,13 +20,13 @@ test_red_black_tree_initialization(const_pointer data)
static void
test_red_black_tree_insertion(const_pointer data)
{
struct RBTree* tree = rb_tree_new(cry_int_compare);
struct CryRbTree* tree = cry_rbtree_new(cry_int_compare);
const int* keys = cry_cast(const int*, data);
assert(tree->nodes == 0);
while(*keys > 0) {
assert(rb_tree_insert(tree, keys) != 0);
assert(cry_rbtree_insert(tree, keys, 0) != 0);
++keys;
}
......@@ -35,7 +35,7 @@ test_red_black_tree_insertion(const_pointer data)
keys = cry_cast(const int*, data);
while(*keys > 0) {
struct RBNode* node = rb_tree_lookup(tree, keys);
struct CryRbNode* node = cry_rbtree_lookup(tree, keys);
assert(node != 0);
assert(node->entry == keys);
......@@ -43,7 +43,7 @@ test_red_black_tree_insertion(const_pointer data)
++keys;
}
rb_tree_clear(tree, 0);
cry_rbtree_clear(tree, 0, 0);
cry_free(tree);
}
......@@ -51,14 +51,14 @@ test_red_black_tree_insertion(const_pointer data)
static void
test_red_black_tree_removal(const_pointer list)
{
struct RBTree* tree = rb_tree_new(cry_int_compare);
struct CryRbTree* tree = cry_rbtree_new(cry_int_compare);
const int* keys = cry_cast(const int*, list);
struct RBNode* data = 0;
struct CryRbNode* data = 0;
assert(tree->nodes == 0);
while(*keys > 0) {
assert(rb_tree_insert(tree, keys) != 0);
assert(cry_rbtree_insert(tree, keys, 0) != 0);
++keys;
}
......@@ -67,48 +67,48 @@ test_red_black_tree_removal(const_pointer list)
keys = cry_cast(const int*, list);
// remove 3
data = rb_tree_remove(tree, keys + 4);
data = cry_rbtree_remove(tree, keys + 4);
assert(data != 0 && data->entry == keys + 4);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// remove 12
data = rb_tree_remove(tree, keys + 2);
data = cry_rbtree_remove(tree, keys + 2);
assert(data != 0 && data->entry == keys + 2);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// remove 17
data = rb_tree_remove(tree, keys + 9);
data = cry_rbtree_remove(tree, keys + 9);
assert(data != 0 && data->entry == keys + 9);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// remove 18
data = rb_tree_remove(tree, keys + 7);
data = cry_rbtree_remove(tree, keys + 7);
assert(data != 0 && data->entry == keys + 7);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// remove 15
data = rb_tree_remove(tree, keys + 3);
data = cry_rbtree_remove(tree, keys + 3);
assert(data != 0 && data->entry == keys + 3);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// remove 16
data = rb_tree_remove(tree, keys + 8);
data = cry_rbtree_remove(tree, keys + 8);
assert(data != 0 && data->entry == keys + 8);
rb_node_free(data, 0);
cry_rbnode_free(data, 0, 0);
// contains 4
assert(rb_tree_lookup(tree, keys) != 0);
assert(cry_rbtree_lookup(tree, keys) != 0);
// contains 7
assert(rb_tree_lookup(tree, keys + 1) != 0);
assert(cry_rbtree_lookup(tree, keys + 1) != 0);
// contains 5
assert(rb_tree_lookup(tree, keys + 5) != 0);
assert(cry_rbtree_lookup(tree, keys + 5) != 0);
// contains 14
assert(rb_tree_lookup(tree, keys + 6) != 0);
assert(cry_rbtree_lookup(tree, keys + 6) != 0);
rb_tree_clear(tree, 0);
cry_rbtree_clear(tree, 0, 0);
cry_free(tree);
}
......@@ -116,14 +116,14 @@ test_red_black_tree_removal(const_pointer list)
static void
test_red_black_tree_traversal(const_pointer list)
{
struct RBTree* tree = rb_tree_new(cry_int_compare);
struct CryRbTree* tree = cry_rbtree_new(cry_int_compare);
const int* keys = cry_cast(const int*, list);
struct RBNode* data = 0;
struct CryRbNode* data = 0;
assert(tree->nodes == 0);
while(*keys > 0) {
assert(rb_tree_insert(tree, keys) != 0);
assert(cry_rbtree_insert(tree, keys, 0) != 0);
++keys;
}
......@@ -131,20 +131,20 @@ test_red_black_tree_traversal(const_pointer list)
keys = cry_cast(const int*, list);
data = rb_node_first(tree);
data = cry_rbnode_first(tree);
while(data != 0) {
data = rb_node_next(data);
data = cry_rbnode_next(data);
}
data = rb_node_last(tree);
data = cry_rbnode_last(tree);
while(data != 0) {
data = rb_node_prev(data);
data = cry_rbnode_prev(data);
}
rb_tree_clear(tree, 0);
cry_rbtree_clear(tree, 0, 0);
cry_free(tree);
}
......