#include "mem.h"
#include "rbt.h"
+//nodes are compared by memory address by default
+static int rbt_default_comparator(void* a, void* b){
+ return (a == b ? 0 : (a<b ? -1 : 1 ));
+}
+
+/* -------------------------------- */
+/* destructors / constructors */
+/* -------------------------------- */
+
+/* rbt_t */
static void rbt_free(void* v_tree){
rbt_t* tree = (rbt_t*) v_tree;
if(tree && tree->root) mem_release(tree->root);
}
+rbt_t* rbt_new(comparator_t comparator){
+ rbt_t* tree = mem_allocate(sizeof(rbt_t), &rbt_free);
+ tree->root = NULL;
+ tree->comp = comparator ? comparator : rbt_default_comparator;
+ return tree;
+}
+/* rbt_node_t */
static void rbt_node_free(void* v_node){
rbt_node_t* node = (rbt_node_t*) v_node;
if(node){
if(node->right) mem_release(node->right);
}
}
-
-static int rbt_default_comparator(void* a, void* b){
- return (a == b ? 0 : (a<b ? -1 : 1 ));
-}
-
rbt_node_t* rbt_node_new(void* contents){
rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
node->left = NULL;
return node;
}
-rbt_t* rbt_new(comparator_t comparator){
- rbt_t* tree = mem_allocate(sizeof(rbt_t), &rbt_free);
- tree->root = NULL;
- tree->comp = comparator ? comparator : rbt_default_comparator;
- return tree;
-}
-//leaves are NULL and black implicitly
+/* ---------------------------------------- */
+/* informational / querying functions */
+/* ---------------------------------------- */
+
rbt_color_t rbt_node_color(rbt_node_t* node){
+ //leaves are NULL and black implicitly
return (node ? node->color : BLACK);
}
+static rbt_node_t* rbt_lookup_node(rbt_t* tree, rbt_node_t* node, void* value){
+ rbt_node_t* ret = NULL;
+ if(node){
+ int c = tree->comp(value, node->contents);
+ if(c == 0) ret = node;
+ else if(c > 0) ret = rbt_lookup_node(tree, node->right, value);
+ else if(c < 0) ret = rbt_lookup_node(tree, node->left, value);
+ }
+ return ret;
+}
+
+rbt_node_t* rbt_lookup(rbt_t* tree, void* value){
+ return rbt_lookup_node(tree, tree->root, value);
+}
+
+
+/* ----------------------------------------- */
+/* generally helpful tree manipulation */
+/* ----------------------------------------- */
+
typedef enum {
LEFT = 0, RIGHT
} direction_t;
} /* else rotation isn't allowed */
}
+
+/* -------------------- */
+/* insertion code */
+/* -------------------- */
+
static void rbt_ins_rebalance(rbt_t* tree, rbt_node_t* node, direction_t heavy_side){
rbt_node_t* parent = node->parent;
rbt_node_t* grandparent = (parent ? parent->parent : NULL);
}
-static rbt_node_t* rbt_lookup_node(rbt_t* tree, rbt_node_t* node, void* value){
- rbt_node_t* ret = NULL;
- if(node){
- int c = tree->comp(value, node->contents);
- if(c == 0) ret = node;
- else if(c > 0) ret = rbt_lookup_node(tree, node->right, value);
- else if(c < 0) ret = rbt_lookup_node(tree, node->left, value);
- }
- return ret;
-}
-
-rbt_node_t* rbt_lookup(rbt_t* tree, void* value){
- return rbt_lookup_node(tree, tree->root, value);
-}
+/* ------------------- */
+/* removal code */
+/* ------------------- */
//node has a count -1 of black nodes to leaves relative to the rest of the tree
static void rbt_del_rebalance(rbt_t* tree, rbt_node_t* node){
node->parent = NULL;
mem_release(node);
}
+
void rbt_delete(rbt_t* tree, void* value){
rbt_node_t* doomed = rbt_lookup(tree, value);
if(doomed) rbt_delete_node(tree, doomed);
RED = 0,
BLACK
} rbt_color_t;
-
-typedef enum {
- OK = 0,
- OUT_OF_ORDER,
- BAD_ROOT_COLOR,
- BLACK_NODES_UNBALANCED,
- UNKNOWN_COLOR,
- RED_WITH_RED_CHILD,
- BAD_PARENT_POINTER,
- SELF_REFERENCE,
-} rbt_status_t;
typedef int (*comparator_t)(void* p_a, void* p_b);
comparator_t comp;
} rbt_t;
-
-rbt_node_t* rbt_node_new(void* contents);
rbt_t* rbt_new(comparator_t comparator);
+rbt_node_t* rbt_node_new(void* contents);
+rbt_color_t rbt_node_color(rbt_node_t* ndoe);
+rbt_node_t* rbt_lookup(rbt_t* tree, void* value);
//returns a pointer to the new node
rbt_node_t* rbt_insert(rbt_t* tree, void* value);
void rbt_delete(rbt_t* tree, void* value);
//look up a node in the tree with the given value
-rbt_node_t* rbt_lookup(rbt_t* tree, void* value);
-rbt_color_t rbt_node_color(rbt_node_t* ndoe);
#ifdef __cplusplus
}