]> git.mdlowis.com Git - projs/libcds.git/commitdiff
move test/check functions to test_rbt.c; make rbt_node_color public & rename
authora bellenir <a@bellenir.com>
Thu, 14 Aug 2014 05:27:22 +0000 (05:27 +0000)
committera bellenir <a@bellenir.com>
Thu, 14 Aug 2014 05:27:22 +0000 (05:27 +0000)
source/rbt/rbt.c
source/rbt/rbt.h
tests/test_rbt.c

index 3cbc254715045754e0745a4e9d64598e59f49b9e..236c48433aafb6c83e244399e866ef510528d53f 100644 (file)
@@ -37,7 +37,7 @@ rbt_t* rbt_new(comparator_t comparator){
 }
 
 //leaves are NULL and black implicitly
-static rbt_color_t node_color(rbt_node_t* node){
+rbt_color_t rbt_node_color(rbt_node_t* node){
        return (node ? node->color : BLACK);
 }
 
@@ -80,9 +80,9 @@ static void rbt_ins_recolor(rbt_t* tree, rbt_node_t* node){
        rbt_node_t* uncle = (grandparent ? (parent == grandparent->left ? grandparent->right : grandparent->left) : NULL);
        if(NULL == parent){
                node->color = BLACK;
-       }else if(BLACK == node_color(parent)){
+       }else if(BLACK == rbt_node_color(parent)){
                /* dont need to do anything */
-       }else if(node_color(uncle) == RED){
+       }else if(rbt_node_color(uncle) == RED){
                //parent and uncle are both red. both can be painted black
                grandparent->color = RED;
                parent->color = BLACK;
@@ -152,18 +152,18 @@ static void rbt_del_rebalance(rbt_t* tree, rbt_node_t* node){
                rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left);
                rbt_node_t* inside_nibling = sib ? (node_side == LEFT ? sib->left : sib->right) : NULL;
                rbt_node_t* outside_nibling = sib ? (node_side == LEFT ? sib->right : sib->left) : NULL;
-               if(RED == node_color(sib)){
+               if(RED == rbt_node_color(sib)){
                        //rotate so sib is black & recurse w/ new scenario
                        rotate(tree, parent, node_side);
                        parent->color = RED;
                        sib->color = BLACK;
                        rbt_del_rebalance(tree, node);
-               }else if(BLACK == node_color(inside_nibling) && BLACK == node_color(outside_nibling)){
+               }else if(BLACK == rbt_node_color(inside_nibling) && BLACK == rbt_node_color(outside_nibling)){
                        //both niblings are black ; can paint sib red & rebalance on parent
                        sib->color = RED;
-                       if(RED == node_color(parent)) parent->color = BLACK;
+                       if(RED == rbt_node_color(parent)) parent->color = BLACK;
                        else rbt_del_rebalance(tree, parent);
-               }else if(BLACK == node_color(outside_nibling)){
+               }else if(BLACK == rbt_node_color(outside_nibling)){
                        //convert "inside" case to "outside" case & recurse w/ new scenario
                        rotate(tree, sib, (node_side == LEFT ? RIGHT : LEFT));
                        sib->color = RED;
@@ -202,11 +202,11 @@ static void rbt_delete_node(rbt_t* tree, rbt_node_t* node){
        }else{
                //node has at most one non-leaf child
                rbt_node_t* child = NULL;
-               if(RED == node_color(node)){
+               if(RED == rbt_node_color(node)){
                        //node cannot have children
                        if(node == parent->left) parent->left = NULL;
                        else parent->right = NULL;
-               } else if(RED == node_color(node->left) || RED == node_color(node->right)){
+               } else if(RED == rbt_node_color(node->left) || RED == rbt_node_color(node->right)){
                        child = node->left ? node->left : node->right;
                        child->color = BLACK;
                } else {
@@ -230,51 +230,3 @@ void rbt_delete(rbt_t* tree, void* value){
        if(doomed) rbt_delete_node(tree, doomed);
 }
 
-/* THE FOLLOWING FUNCTIONS (TO EOF) ARE USED FOR TESTING PURPOSES ONLY */
-
-//if path to the left != path to the right, return -1 (invalid)
-int count_black_nodes_to_leaf(rbt_node_t* node){
-       int ret = 0;
-       if(node){
-               int leftcount = count_black_nodes_to_leaf(node->left);
-               int rightcount = count_black_nodes_to_leaf(node->right);
-               if(leftcount != rightcount) ret = -1;
-               else if(node->color == BLACK) ret = leftcount+1;
-               else ret = leftcount;
-       }
-       return ret;
-}
-
-static rbt_status_t rbt_check_node(rbt_t* tree, rbt_node_t* node, void* min_val, void* max_val){
-       rbt_status_t ret = OK;
-       void* neg1 = mem_box(-1);
-       if(node){
-               if(node->color != RED && node->color != BLACK) ret = UNKNOWN_COLOR;
-               else if(node->color == RED && (node_color(node->left) != BLACK && node_color(node->right) != BLACK))
-                       ret = RED_WITH_RED_CHILD;
-               else if(tree->comp(min_val, neg1) > 0 && tree->comp(node->contents, min_val) < 0) ret = OUT_OF_ORDER;
-               else if(tree->comp(max_val, neg1) > 0 && tree->comp(node->contents, max_val) > 0) ret = OUT_OF_ORDER;
-               else if(node->left == node || node->right == node) ret = SELF_REFERENCE;
-               else if(node->left && node->left->parent != node) ret = BAD_PARENT_POINTER;
-               else if(node->right && node->right->parent != node) ret = BAD_PARENT_POINTER;
-               if(ret == OK) ret = rbt_check_node(tree, node->left, min_val, node->contents);
-               if(ret == OK) ret = rbt_check_node(tree, node->right, node->contents, max_val);
-       }
-       mem_release(neg1);
-       return ret;
-}
-
-//check the contents of the given tree/node as valid
-rbt_status_t rbt_check_status(rbt_t* tree){
-       rbt_status_t ret = OK;
-       void* neg1 = mem_box(-1);
-       if(tree){
-               ret = rbt_check_node(tree, tree->root, neg1, neg1);
-               if(ret == OK && tree->root && tree->root->parent) ret = BAD_PARENT_POINTER;
-               if(ret == OK && node_color(tree->root) != BLACK) ret = BAD_ROOT_COLOR;
-               if(ret == OK && count_black_nodes_to_leaf(tree->root) == -1) ret = BLACK_NODES_UNBALANCED;
-       }
-       mem_release(neg1);
-       return ret;
-}
-
index 28f621c166b8af896e15d6081e6e513d32577a22..e98e0f5d35eb70970eea091ad1d61b6061ea997f 100644 (file)
@@ -44,10 +44,7 @@ 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);
-
-//TEST FUNCTIONS:
-rbt_status_t rbt_check_status(rbt_t* tree);
-//rbt_status_t rbt_check_node(rbt_node_t* node, void* min_val, void* max_val);
+rbt_color_t rbt_node_color(rbt_node_t* ndoe);
 
 #ifdef __cplusplus
 }
index 41a532a78100e60dbb1cdc900f3c2cdad30f2cc4..f1c03c7b21adf2996ce75826976641a2b4cb078a 100644 (file)
@@ -13,6 +13,52 @@ static int test_compare(void* a, void* b){
        return (ia == ib ? 0 : (ia<ib ? -1 : 1 ));
 }
 
+//if path to the left != path to the right, return -1 (invalid)
+static int count_black_nodes_to_leaf(rbt_node_t* node){
+       int ret = 0;
+       if(node){
+               int leftcount = count_black_nodes_to_leaf(node->left);
+               int rightcount = count_black_nodes_to_leaf(node->right);
+               if(leftcount != rightcount) ret = -1;
+               else if(node->color == BLACK) ret = leftcount+1;
+               else ret = leftcount;
+       }
+       return ret;
+}
+
+static rbt_status_t rbt_check_node(rbt_t* tree, rbt_node_t* node, void* min_val, void* max_val){
+       rbt_status_t ret = OK;
+       void* neg1 = mem_box(-1);
+       if(node){
+               if(node->color != RED && node->color != BLACK) ret = UNKNOWN_COLOR;
+               else if(node->color == RED && (rbt_node_color(node->left) != BLACK && rbt_node_color(node->right) != BLACK))
+                       ret = RED_WITH_RED_CHILD;
+               else if(tree->comp(min_val, neg1) > 0 && tree->comp(node->contents, min_val) < 0) ret = OUT_OF_ORDER;
+               else if(tree->comp(max_val, neg1) > 0 && tree->comp(node->contents, max_val) > 0) ret = OUT_OF_ORDER;
+               else if(node->left == node || node->right == node) ret = SELF_REFERENCE;
+               else if(node->left && node->left->parent != node) ret = BAD_PARENT_POINTER;
+               else if(node->right && node->right->parent != node) ret = BAD_PARENT_POINTER;
+               if(ret == OK) ret = rbt_check_node(tree, node->left, min_val, node->contents);
+               if(ret == OK) ret = rbt_check_node(tree, node->right, node->contents, max_val);
+       }
+       mem_release(neg1);
+       return ret;
+}
+
+//check the contents of the given tree/node as valid
+static rbt_status_t rbt_check_status(rbt_t* tree){
+       rbt_status_t ret = OK;
+       void* neg1 = mem_box(-1);
+       if(tree){
+               ret = rbt_check_node(tree, tree->root, neg1, neg1);
+               if(ret == OK && tree->root && tree->root->parent) ret = BAD_PARENT_POINTER;
+               if(ret == OK && rbt_node_color(tree->root) != BLACK) ret = BAD_ROOT_COLOR;
+               if(ret == OK && count_black_nodes_to_leaf(tree->root) == -1) ret = BLACK_NODES_UNBALANCED;
+       }
+       mem_release(neg1);
+       return ret;
+}
+
 static void test_setup(void) { }
 //-----------------------------------------------------------------------------
 // Begin Unit Tests