private bool IsNullOrBlack(RBNode <T> node) { return(node.IsNull() || !node.IsRed); }
private void RemoveNode(RBNode <T> node) { RBNode <T> tmp = null; // after the below step, tmp points to the actual node to be deleted; if (node.Degree == 2) { tmp = node.Left; path[++p] = tmp; while (tmp.Right != null) { tmp = tmp.Right; path[++p] = tmp; } node.Item = tmp.Item; } else { tmp = node; } RBNode <T> newTmp = tmp.Left; if (newTmp.IsNull()) { newTmp = tmp.Right; } if (p > 0) { RBNode <T> parent = path[p - 1]; if (parent.Left == tmp) { parent.Left = newTmp; } else { parent.Right = newTmp; } // if the deleted is black and its single child is red. if (!tmp.IsRed && IsRed(newTmp)) { newTmp.IsRed = false; return; } } else { // if delete the root node. _head = newTmp; if (_head.IsNotNull()) { _head.IsRed = false; } return; } path[p] = newTmp; if (IsRed(tmp)) { // if the deleted is red, directly return. return; } // the deleted and its child are both BLACK. while (p > 0) { RBNode <T> current = path[p]; RBNode <T> parent = path[p - 1]; bool currentIsLeft = (parent.Left == current); RBNode <T> sibling = currentIsLeft ? parent.Right : parent.Left; if (IsRed(sibling)) { RBNode <T> newRoot; if (currentIsLeft) { newRoot = RR(parent); } else { newRoot = LL(parent); } ReplaceChildOfNodeOrRoot(p > 1 ? path[p - 2] : null, parent, newRoot); sibling.IsRed = false; parent.IsRed = true; path[p - 1] = newRoot; path[p] = parent; path[++p] = current; } else { // black sibling && black sibling-left && black sibling-right if (IsNullOrBlack(sibling.Left) && IsNullOrBlack(sibling.Right)) { if (parent.IsRed) { parent.IsRed = false; sibling.IsRed = true; if (current.IsNotNull()) { // TODO: not needed? current.IsRed = false; } break; } else { // current must be black? parent.IsRed = IsRed(current); if (current.IsNotNull()) { current.IsRed = false; } sibling.IsRed = true; p--; // continue to backtrack. } } else { RBNode <T> newRoot; if (currentIsLeft) { if (IsRed(sibling.Right)) { newRoot = RR(parent); sibling.Right.IsRed = false; } else { newRoot = RL(parent); } } else { if (IsRed(sibling.Left)) { newRoot = LL(parent); sibling.Left.IsRed = false; } else { newRoot = LR(parent); } } if (current.IsNotNull()) { current.IsRed = false; } newRoot.IsRed = parent.IsRed; parent.IsRed = false; ReplaceChildOfNodeOrRoot(p > 1 ? path[p - 2] : null, parent, newRoot); break; } } } }