void RBTreeDelete(RBTree_t *tree, struct RBNode_t *node) { struct RBNode_t *y = node; struct RBNode_t *x; RBColor_t origincolor = y->mColor; if(node->mLeft == &tree->mSentinelLeaf) { x = node->mRight; RBTreeTransplant(tree, node, node->mRight); } else if(node->mRight == &tree->mSentinelLeaf) { x = node->mLeft; RBTreeTransplant(tree, node, node->mLeft); } else { y = RBTreeMinimum(node->mRight, &tree->mSentinelLeaf); origincolor = y->mColor; x = y->mRight; if(y->mParent == node) { x->mParent = y; } else { RBTreeTransplant(tree, y, y->mRight); y->mRight = node->mRight; y->mRight->mParent = y; } RBTreeTransplant(tree, node, y); y->mLeft = node->mLeft; y->mLeft->mParent = y; y->mColor = node->mColor; } if(origincolor == RB_BLACK) { RBTreeDeleteFixup(tree, x); } }
/* z is deleted node; y is the node which position on the tree will be replaced(Note that y not must be z); x is the node that replacing y's position on the tree; */ void RBTreeDelete(struct rb_tree *rb, rb_key_t key) { struct rb_node *x, *y, *z; int yOriginColor; z = RBTreeSearch(rb, key); if (z == rb->nil) return ; rb->size--; y = z; yOriginColor = y->color; if (z->left == rb->nil) { x = z->right; RBTreeTransplant(rb, z, z->right); } else if (z->right == rb->nil) { x = z->left; RBTreeTransplant(rb, z, z->left); } else { y = RBTreeMin(rb, z->right); yOriginColor = y->color; x = y->right; if (y->p != z) { RBTreeTransplant(rb, y, y->right); y->right = z->right; y->right->p = y; } RBTreeTransplant(rb, z, y); y->left = z->left; y->left->p = y; y->color = z->color; } if (yOriginColor == BLACK && x != rb->nil) RBTreeDeleteFixup(rb, x); free(z); }