|
|
@ -104,97 +104,9 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp) |
|
|
* rebalancing process...(this does not make much sense, but |
|
|
* rebalancing process...(this does not make much sense, but |
|
|
* to be honest I don't know now.) |
|
|
* to be honest I don't know now.) |
|
|
*/ |
|
|
*/ |
|
|
while(1) { |
|
|
|
|
|
TR_Tree sibling; |
|
|
|
|
|
|
|
|
|
|
|
// case 1 |
|
|
|
|
|
if (NULL == TR_TREE_PARENT(node)) { |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sibling = TR_TREE_SIBLING(node); |
|
|
|
|
|
if (NULL != sibling && rbRed == sibling->color) { |
|
|
|
|
|
// case 2 |
|
|
|
|
|
node->parent->color = rbRed; |
|
|
|
|
|
sibling->color = rbBlack; |
|
|
|
|
|
|
|
|
|
|
|
if (NULL != node->parent->right && node != node->parent->right) { |
|
|
|
|
|
TR_TREE_ROTATE(left, this, node->parent); |
|
|
|
|
|
} else { |
|
|
|
|
|
TR_TREE_ROTATE(right, this, node->parent); |
|
|
|
|
|
} |
|
|
|
|
|
sibling = TR_TREE_SIBLING(node); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (NULL == sibling |
|
|
|
|
|
|| (rbBlack == sibling->color |
|
|
|
|
|
&& TR_TREE_NODE_BLACK(sibling->left) |
|
|
|
|
|
&& TR_TREE_NODE_BLACK(sibling->right))) { |
|
|
|
|
|
// case 3/4 |
|
|
|
|
|
if (NULL != sibling) { |
|
|
|
|
|
sibling->color = rbRed; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (rbBlack == node->parent->color) { |
|
|
|
|
|
// case 3 |
|
|
|
|
|
node = node->parent; |
|
|
|
|
|
continue; |
|
|
|
|
|
} else { |
|
|
|
|
|
// case 4 |
|
|
|
|
|
node->parent->color = rbBlack; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// case 5 |
|
|
|
|
|
if (NULL != sibling && rbBlack == sibling->color) { |
|
|
|
|
|
|
|
|
|
|
|
if (node == node->parent->left |
|
|
|
|
|
&& TR_TREE_NODE_BLACK(sibling->right) |
|
|
|
|
|
&& TR_TREE_NODE_STRICT_RED(sibling->left)) { |
|
|
|
|
|
|
|
|
|
|
|
sibling->color = rbRed; |
|
|
|
|
|
sibling->left->color = rbBlack; |
|
|
|
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(right, this, sibling); |
|
|
|
|
|
|
|
|
|
|
|
} else if (node == node->parent->right |
|
|
|
|
|
&& TR_TREE_NODE_BLACK(sibling->left) |
|
|
|
|
|
&& TR_TREE_NODE_STRICT_RED(sibling->right)) { |
|
|
|
|
|
|
|
|
|
|
|
sibling->color = rbRed; |
|
|
|
|
|
sibling->right->color = rbBlack; |
|
|
|
|
|
|
|
|
|
|
|
TR_TREE_ROTATE(left, this, sibling); |
|
|
|
|
|
} |
|
|
|
|
|
sibling = TR_TREE_SIBLING(node); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// case 6 |
|
|
|
|
|
// do we need to reinitialize sibling here? |
|
|
|
|
|
if (NULL != sibling) { |
|
|
|
|
|
sibling->color = node->parent->color; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (NULL != node && NULL != node->parent) { |
|
|
|
|
|
node->parent->color = rbBlack; |
|
|
|
|
|
|
|
|
|
|
|
if (NULL != node->parent->right |
|
|
|
|
|
&& node != node->parent->right) { |
|
|
|
|
|
|
|
|
|
|
|
if (NULL != sibling->right) { |
|
|
|
|
|
sibling->right->color = rbBlack; |
|
|
|
|
|
} |
|
|
|
|
|
TR_TREE_ROTATE(left, this, node->parent); |
|
|
|
|
|
} else { |
|
|
|
|
|
if (NULL != sibling->left) { |
|
|
|
|
|
sibling->left->color = rbBlack; |
|
|
|
|
|
} |
|
|
|
|
|
TR_TREE_ROTATE(right, this, node->parent); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
TR_Tree sibling = TR_TREE_SIBLING(node); |
|
|
|
|
|
TR_TREE_BALANCE_DELETE(this, node, sibling); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
TR_delete(del_node); |
|
|
TR_delete(del_node); |
|
|
|