public:
void removeElement(const Key& k) // remove using key
throw(NonexistentElementException) {
BTPosition u = finder(k, T.root()); // find the node
if (u.isNull()) // not found?
throw NonexistentElementException("Remove nonexistent element");
BTPosition r = remover(u); // remove u
if (T.isRoot(r) || isRed(r) || wasParentRed(r))
setBlack(r); // fix by color change
else // r, parent both black
remedyDoubleBlack(r); // fix double-black r
}
protected:
void remedyDoubleBlack(const BTPosition& r) { // fix double-black r
BTPosition x, y, z;
x = T.parent(r);
y = T.sibling(r);
if (isBlack(y)) {
if (hasRedChild(y)) { // Case 1: restructuring
z = redChild(y);
Color oldColor = color(x); // save top vertex color
z = T.restructure(z); // restructure x,y,z
setColor(z, oldColor); setBlack(r); // fix colors
setBlack(T.leftChild(z)); setBlack(T.rightChild(z));
}
else { // Case 2: recoloring
setBlack(r); setRed(y); // r=black, y=red
if (isBlack(x) && !T.isRoot(x))
remedyDoubleBlack(x); // fix double-black x
setBlack(x);
}
}
else { // Case 3: adjustment
if (y == T.rightChild(x)) z = T.rightChild(y); // z is the grandchild
else z = T.leftChild(y); // ...on same side as y
T.restructure(z); // restructure x,y,z
setBlack(y); setRed(x); // y=black, x=red
remedyDoubleBlack(r); // fix by Case 1 or 2
}
}