]> git.mdlowis.com Git - projs/libcds.git/commitdiff
handle deleting root in existing cases
authora bellenir <a@bellenir.com>
Wed, 6 Aug 2014 21:26:48 +0000 (21:26 +0000)
committera bellenir <a@bellenir.com>
Wed, 6 Aug 2014 21:26:48 +0000 (21:26 +0000)
source/rb/rb.c
tests/test_rb.c

index dccd0e2a4b64bed72bb261f0baab799a99a28236..990715e926352a7bf518ea462d66c7c121a90fce 100644 (file)
@@ -184,7 +184,8 @@ static void rb_tree_delete_node(rb_tree_t* tree, rb_node_t* node){
                        //single red child, to the left
                        rb_node_t* child = node->left;
                        child->parent = parent;
-                       if(parent->left == node) parent->left = child;
+                       if(NULL == parent) tree->root = child;
+                       else if(parent->left == node) parent->left = child;
                        else parent->right = child;
                        //safe to destroy node->right ; it is a NULL leaf
                        child->color = BLACK;
@@ -195,7 +196,8 @@ static void rb_tree_delete_node(rb_tree_t* tree, rb_node_t* node){
                        //single red child, to the right
                        rb_node_t* child = node->right;
                        child->parent = parent;
-                       if(parent->left == node) parent->left = child;
+                       if(NULL == parent) tree->root = child;
+                       else if(parent->left == node) parent->left = child;
                        else parent->right = child;
                        child->color = BLACK;
                        node->right = NULL;
index e93fe86cfe2af5f1d2eab448d27b1c2283d64d26..ea6d9f0f1891adc2d15c611712a58e58549a38cf 100644 (file)
@@ -419,7 +419,44 @@ TEST_SUITE(RB) {
                mem_release(tree);
     }
        //second class: deleting nodes that have two children
-       //third class: special cases
-       TEST(Verify_rb_delete_root){}
+       //third class: special cases: deleting root
+       TEST(Verify_rb_delete_root_node_with_single_red_left_child){
+               rb_tree_t* tree = rb_tree_new();
+               rb_node_t* node1 = rb_tree_insert(tree, 88);
+               rb_node_t* node2 = rb_tree_insert(tree, 42);
+               mem_retain(node1);
+               rb_tree_delete(tree, 88);
+               CHECK(1 == mem_num_references(node1));
+               CHECK(node2 == tree->root);
+               CHECK(NULL == node2->left);
+               CHECK(NULL == node2->right);
+               CHECK(NULL == node2->parent);
+               //check node1 pointers are nulld
+               CHECK(NULL == node1->parent);
+               CHECK(NULL == node1->left);
+               CHECK(NULL == node1->right);
+               CHECK(rb_tree_is_valid(tree));
+               mem_release(node1);
+               mem_release(tree);
+       }
+       TEST(Verify_rb_delete_root_node_with_single_red_right_child){
+               rb_tree_t* tree = rb_tree_new();
+               rb_node_t* node1 = rb_tree_insert(tree, 42);
+               rb_node_t* node2 = rb_tree_insert(tree, 88);
+               mem_retain(node1);
+               rb_tree_delete(tree, 42);
+               CHECK(1 == mem_num_references(node1));
+               CHECK(node2 == tree->root);
+               CHECK(NULL == node2->left);
+               CHECK(NULL == node2->right);
+               CHECK(NULL == node2->parent);
+               //check node1 pointers are nulld
+               CHECK(NULL == node1->parent);
+               CHECK(NULL == node1->left);
+               CHECK(NULL == node1->right);
+               CHECK(rb_tree_is_valid(tree));
+               mem_release(node1);
+               mem_release(tree);
+       }
 }