Node *_delRedBlackTree(Node **rootPtr, Node *newNode, int (*compareNode)(void *data, void *object)){ Node *root = *rootPtr, *node , *successorNode; if(root == NULL) Throw(ERR_NODE_UNAVAIBLE); else if(compareNode(root->data, newNode->data) == 1) node = _delRedBlackTree( &root->right, newNode, compareNode); else if(compareNode(root->data, newNode->data) == -1) node = _delRedBlackTree( &root->left, newNode, compareNode); else{ if(root->left || root->right){ //Checking is the removeNode has childNode successorNode = removeNextLargerSuccessor(&(*rootPtr)->right); successorNode->left = (*rootPtr)->left; successorNode->right = (*rootPtr)->right; *rootPtr = successorNode; } else *rootPtr = NULL; return root; } caseSelect(&(*rootPtr)); return node; }
/** Encounter case 3 on the left child after remove successor (with case 1a appear after rotate) * * parent's left parent's left parent's left parent's left * | | | | * v v v v * 10(b) 10(b) 10(b) 10(b) * / \ successor 1 / \ / \ / \ * 4(b) 15(b) ------------> 4(b) 15(b) ------------> 7(b) 15(b) ------------> 7(b) 15(b) * / \ / \ // \ / \ / \ / \ / \ / \ * 1(b) 7(r) 13(b) 20(b) NULL 7(r) 13(b) 20(b) 4(r) 8(b) 13(b) 20(b) 5(r) 8(b) 13(b) 20(b) * / \ / \ // \ / \ * 5(b) 8(b) 5(b) 8(b) NULL 5(b) 4(b) 6(b) * \ \ \ * 6(r) 6(r) 6(r) */ void test_removeNextLargerSuccessor_given_nodes_1_4_5_6_7_8_10_13_15_20_should_remove_successor_1(void) { setNode(&node6, NULL, NULL, 'r'); setNode(&node5, NULL, &node6, 'b'); setNode(&node8, NULL, NULL, 'b'); setNode(&node7, &node5, &node8, 'r'); setNode(&node13, NULL, NULL, 'b'); setNode(&node20, NULL, NULL, 'b'); setNode(&node1, NULL, NULL, 'b'); setNode(&node4, &node1, &node7, 'b'); setNode(&node15, &node13, &node20, 'b'); setNode(&node10, &node4, &node15, 'b'); Node *parent = &node10, *removeNode; removeNode = removeNextLargerSuccessor(&parent); TEST_ASSERT_EQUAL_PTR(&node10, parent); TEST_ASSERT_EQUAL_PTR(&node1, removeNode); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node4); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node6); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node8); TEST_ASSERT_EQUAL_NODE(&node4, &node6, 'r', &node5); TEST_ASSERT_EQUAL_NODE(&node5, &node8, 'b', &node7); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node13); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node20); TEST_ASSERT_EQUAL_NODE(&node13, &node20, 'b', &node15); TEST_ASSERT_EQUAL_NODE(&node7, &node15, 'b', &node10); }
/** * parent parent * | successor \\ * v 2 v * 2(b) ------------> - * / \ * - - * */ void test_removeNextLargerSuccessor_remove_2_from_the_tree_with_2_node(void) { setNode(&node2, NULL, NULL, 'b'); Node *parent = &node2; Node *removeNode; removeNode = removeNextLargerSuccessor(&parent); TEST_ASSERT_NULL(parent); TEST_ASSERT_EQUAL(1, isDoubleBlack(&parent, removeNode)); }
/** * parent parent * | | * v successor v * 2(b) 2 3(b) * \ --------------> * 3(r) */ void test_removeNextLargerSuccessor_remove_3_from_the_tree_with_2_3_nodes(void) { setNode(&node3, NULL, NULL, 'r'); setNode(&node2, NULL, &node3, 'b'); Node *parent = &node2; Node *removeNode; removeNode = removeNextLargerSuccessor(&parent); TEST_ASSERT_EQUAL_PTR(&node2, removeNode); TEST_ASSERT_EQUAL_PTR(parent, &node3); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node3); }
/** * parent parent * | | * v v * 12(b) successor 12(b) * / \ 1 / \ * 5(b) 18(b) ----------> 5(b) 18(b) * / \ / \ / \ / \ * 1(r) - 13(r) - - - 13(r) - */ void test_removeNextLargerSuccessor_remove_1_from_the_tree_with_1_5_12_13_18_nodes(void) { setNode(&node1, NULL, NULL, 'r'); setNode(&node13, NULL, NULL, 'r'); setNode(&node5, &node1, NULL, 'b'); setNode(&node18, &node13, NULL, 'b'); setNode(&node12, &node5, &node18, 'b'); Node *parent = &node12; Node *removeNode; removeNode = removeNextLargerSuccessor(&parent); TEST_ASSERT_EQUAL_PTR(&node1, removeNode); TEST_ASSERT_EQUAL_PTR(parent, &node12); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'r', &node13); TEST_ASSERT_EQUAL_NODE(NULL, NULL, 'b', &node5); TEST_ASSERT_EQUAL_NODE(&node13, NULL, 'b', &node18); TEST_ASSERT_EQUAL_NODE(&node5, &node18, 'b', &node12); }
Node *removeNextLargerSuccessor(Node **parentPtr){ Node *parent = *parentPtr, *removeNode; if(parent->left == NULL && parent->right == NULL){ removeNode = *parentPtr; *parentPtr = NULL; } else if(parent->left){ removeNode = removeNextLargerSuccessor(&(*parentPtr)->left); if(isDoubleBlack((*parentPtr)->left, removeNode)) caseSelectForSucessor(&(*parentPtr)); } else{ removeNode = parent; *parentPtr = parent->right; (*parentPtr)->color = parent->color; } return removeNode; }
Node *_delRedBlackTree(Node **rootPtr, Node *newNode){ Node *root = *rootPtr, *node , *successorNode; if(root == NULL) Throw(ERR_NODE_UNAVAIBLE); if(root->data == newNode->data){ if(root->left || root->right){ //Checking is the removeNode has childNode successorNode = removeNextLargerSuccessor(&(*rootPtr)->right); successorNode->left = (*rootPtr)->left; successorNode->right = (*rootPtr)->right; *rootPtr = successorNode; } else *rootPtr = NULL; return root; } if(newNode->data > (*rootPtr)->data) node = _delRedBlackTree( &root->right, newNode); if(newNode->data < (*rootPtr)->data) node = _delRedBlackTree( &root->left, newNode); caseSelect(&(*rootPtr)); return node; }