/*******************************************************************************************/ /*******************************************************************************************/ private void DeleteNodeLeaf(Node node) { if (node.Color == NodeColor.RED) { DetachNode(node); } else { NodeDoubleBlack nodeDB = new NodeDoubleBlack(node.Parent, node, null); DetachNode(node); FixDoubleBlackNode(nodeDB); } }
/*******************************************************************************************/ /*******************************************************************************************/ private void FixDoubleBlackNode(NodeDoubleBlack nodeDB) { if (nodeDB.Parent is null) { return; } Node sibling = nodeDB.Sibling; if (sibling != null && sibling.Color == NodeColor.BLACK && HasRedNode(sibling)) { Node siblingRedChild = HasLeftNodeRed(sibling) ? sibling.Left : sibling.Right; if (sibling < sibling.Parent && (HasBothNodesRed(sibling) || HasLeftNodeRed(sibling))) { // Left Left case SetNodeColor(sibling.Left, NodeColor.BLACK); SwapColors(sibling, sibling.Parent); RotateNode(sibling); } else if (sibling < sibling.Parent && siblingRedChild > sibling) { // Left Right Case SwapColors(siblingRedChild, sibling); RotateNode(siblingRedChild); RotateNode(siblingRedChild); } else if ((sibling > sibling.Parent && siblingRedChild > sibling) || HasBothNodesRed(sibling)) { // Right Right Case RotateNode(sibling); SwapColors(sibling, sibling.Parent); } else if (sibling > sibling.Parent && HasLeftNodeRed(sibling)) { // Left Right Case RotateNode(sibling.Left); RotateNode(sibling.Left); } } else if (sibling is null || (sibling.Color == NodeColor.BLACK && HasBothNodesBlack(sibling))) { // Recolour if (nodeDB.Parent.Color == NodeColor.BLACK && sibling != null) { SetNodeColor(sibling, NodeColor.RED); } }
/*******************************************************************************************/ /*******************************************************************************************/ private void DeleteNodeWithOneChild(Node node) { Node child = node.Left is null ? node.Right : node.Left; if (node.Color == NodeColor.RED || child.Color == NodeColor.RED) { SetNodeColor(child, NodeColor.BLACK); DetachNode(node); } else { NodeDoubleBlack nodeDB = new NodeDoubleBlack(node.Parent, node, child); DetachNode(node); FixDoubleBlackNode(nodeDB); } }
/*******************************************************************************************/ /*******************************************************************************************/ private void DeleteNodeWithBothChildren(Node node) { Node leastSuccessor = FindLowestNode(node.Right); Node leastSuccessorChild = leastSuccessor.Right is null ? null : leastSuccessor.Right; if (leastSuccessor.Color == NodeColor.RED || (leastSuccessorChild != null && leastSuccessorChild.Color == NodeColor.RED)) { if (leastSuccessorChild != null) { SetNodeColor(leastSuccessorChild, NodeColor.BLACK); } SwapColors(node, leastSuccessor); DetachNode(node); } else { NodeDoubleBlack nodeDB = new NodeDoubleBlack(leastSuccessor.Parent, leastSuccessor, leastSuccessorChild); SwapColors(node, leastSuccessor); DetachNode(node); FixDoubleBlackNode(nodeDB); } }