]> git.mdlowis.com Git - projs/libcds.git/commitdiff
WIP; split insert & repaint functions
authora bellenir <a@bellenir.com>
Tue, 5 Aug 2014 22:31:11 +0000 (22:31 +0000)
committera bellenir <a@bellenir.com>
Tue, 5 Aug 2014 22:31:11 +0000 (22:31 +0000)
source/rb/rb.c
tests/test_rb.c

index 9fa7ed3c7cddad79d6e545b6e469d635e6607d64..e667cc0e71a084b4f1b07f7fdbc72262ea2c559a 100644 (file)
@@ -32,12 +32,55 @@ rb_tree_t* rb_tree_new(){
        return tree;
 }
 
+//leaves are NULL and black implicitly
+static rb_color_t node_color(rb_node_t* node){
+       return (node ? node->color : BLACK);
+}
+
+//NODE:the node to be inserted
+static void rb_tree_recolor(
+       rb_node_t* node, rb_node_t* parent,
+       rb_node_t* grandparent, rb_node_t* uncle
+){
+       if(NULL == parent){
+               node->color = BLACK;
+       }else if(BLACK == node_color(parent)){
+               /* dont need to do anything */
+       }else if(node_color(parent) == BLACK && node_color(uncle) == BLACK){
+               grandparent->color = RED;
+               parent->color = BLACK;
+               uncle->color = BLACK;
+       }else{
+               //TODO
+       }
+}
+static void rb_tree_insert_node(rb_tree_t* tree,
+       rb_node_t* node, rb_node_t* parent,
+       rb_node_t* grandparent, rb_node_t* uncle
+){
+       if(NULL == parent){ /* inserting root of the tree */
+               tree->root = node;
+               rb_tree_recolor(node, parent, grandparent, uncle);
+       }else if(node->contents < parent->contents){
+               if(parent->left){
+                       rb_tree_insert_node(tree, node, parent->left, parent, parent->right);
+               }else{
+                       parent->left = node;
+                       rb_tree_recolor(node, parent, grandparent, uncle);
+               }
+       }else{
+               if(parent->right){
+                       rb_tree_insert_node(tree, node, parent->right, parent, parent->left);
+               }else{
+                       parent->right = node;
+                       rb_tree_recolor(node, parent, grandparent, uncle);
+               }
+       }
+}
+
 rb_node_t* rb_tree_insert(rb_tree_t* tree, int value){
        rb_node_t* new_node = rb_node_new(value);
-       if(NULL == tree->root){
-               new_node->color = BLACK;
-               tree->root = new_node;
-       }
+       rb_tree_insert_node(tree, new_node, tree->root, NULL, NULL);
        return new_node;
 }
 
@@ -62,8 +105,8 @@ bool rb_node_is_valid(rb_node_t* node, int min_val, int max_val){
        if(node){
                ret &= (node->color == RED || node->color == BLACK);
                if(node->color == RED){
-                       ret &= (!node->left || node->left->color == BLACK);
-                       ret &= (!node->right || node->right->color == BLACK);
+                       ret &= ((node_color(node->left) == BLACK) && 
+                                       (node_color(node->right) == BLACK));
                }
                ret &= ( -1 == min_val || node->contents >= min_val);
                ret &= ( -1 == max_val || node->contents <= max_val);
index 3b75bce36baa675651ea8c83a9a22655ae5651d2..e920c3577e2a328f47802799a220aa1b39022a23 100644 (file)
@@ -45,5 +45,51 @@ TEST_SUITE(RB) {
                CHECK(rb_tree_is_valid(tree));
                mem_release(tree);
     }
+    TEST(Verify_rb_insert_node_to_root_left_works){
+               rb_tree_t* tree = rb_tree_new();
+               rb_node_t* root = rb_tree_insert(tree, 42);
+               rb_node_t* node1 = rb_tree_insert(tree, 31);
+               CHECK(NULL != root);
+               CHECK(NULL != node1);
+               CHECK(tree->root == root);
+               CHECK(31 == node1->contents);
+               CHECK(node1 == root->left);
+               CHECK(NULL == root->right);
+               CHECK(RED == node1->color);
+               CHECK(rb_tree_is_valid(tree));
+               mem_release(tree);
+    }
+    TEST(Verify_rb_insert_node_to_root_right_works){
+               rb_tree_t* tree = rb_tree_new();
+               rb_node_t* root = rb_tree_insert(tree, 42);
+               rb_node_t* node2 = rb_tree_insert(tree, 64);
+               CHECK(NULL != root);
+               CHECK(NULL != node2);
+               CHECK(tree->root == root);
+               CHECK(64 == node2->contents);
+               CHECK(node2 == root->right);
+               CHECK(NULL == root->left);
+               CHECK(RED == node2->color);
+               CHECK(rb_tree_is_valid(tree));
+               mem_release(tree);
+    }
+    TEST(Verify_rb_insert_first_level_works){
+               rb_tree_t* tree = rb_tree_new();
+               rb_node_t* root = rb_tree_insert(tree, 42);
+               rb_node_t* node1 = rb_tree_insert(tree, 31);
+               rb_node_t* node2 = rb_tree_insert(tree, 64);
+               CHECK(NULL != root);
+               CHECK(NULL != node1);
+               CHECK(NULL != node2);
+               CHECK(tree->root == root);
+               CHECK(31 == node1->contents);
+               CHECK(64 == node2->contents);
+               CHECK(node1 == root->left);
+               CHECK(node2 == root->right);
+               CHECK(RED == node1->color);
+               CHECK(RED == node2->color);
+               CHECK(rb_tree_is_valid(tree));
+               mem_release(tree);
+    }
 }