private NodeMeta Remove(NodeMeta meta) { Node node = meta.Node; Side side = Side.Left; Node child = node[side]; if (child == null) { side = Side.Right; child = node[side]; } if (child == null) { // adjust color through parent. if (node.Color == Color.Black) { // Black-Black var sentinel = new SentinelNode(); meta.ParentMeta.Node[meta.SideFromParent] = sentinel; var sentinelMeta = new NodeMeta(meta.ParentMeta, sentinel, meta.SideFromParent, meta.Sibling); return(sentinelMeta); } else { // Red with Black Parent. Done. meta.ParentMeta.Node[meta.SideFromParent] = null; return(null); } } else { NodeMeta leaf = SwapWithAdjacent(meta, side); return(Remove(leaf)); } }
/// <summary> /// Enumerate the nodes in the tree. /// </summary> public IEnumerable <TNode> GetNodes(bool ascending) { RBTreeDirection direction = (ascending ? RBTreeDirection.Right : RBTreeDirection.Left); for (TNode node = SentinelNode.GetNeighbor(direction); node != SentinelNode; node = node.GetNeighbor(direction)) { yield return(node); } }
private NodeMeta SwapWithAdjacent(NodeMeta meta, Side side) { Side otherSide = OtherSide(side); NodeMeta adjacentMeta = Adjacent(side, meta); Node adjacent = adjacentMeta.Node; Node toBeReplaced = meta.Node; Node adjacentParent = adjacentMeta.ParentMeta.Node; adjacentParent[otherSide] = adjacent[side]; // Swap the nodes. // Cache the children of item to be replaced. Node child = adjacent[side]; // Adjacent takes place of node to be removed. meta.ReplaceNode(adjacent); meta.ParentMeta.Node[meta.SideFromParent] = adjacent; adjacent[side] = toBeReplaced[side]; adjacent[otherSide] = toBeReplaced[otherSide]; // Put node to be replaced in adjacent spot adjacentParent[otherSide] = toBeReplaced; toBeReplaced[side] = child; toBeReplaced[otherSide] = null; // This is null, that is how we know it is the leaf adjacentMeta.ReplaceNode(toBeReplaced); // Swap the color Color temp = toBeReplaced.Color; toBeReplaced.Color = adjacent.Color; adjacent.Color = temp; if (child == null) { // We have found the node to remove. Replace it with a sentinal SentinelNode sentinel = new SentinelNode(toBeReplaced.Color); adjacentParent[otherSide] = sentinel; return(new NodeMeta(adjacentMeta.ParentMeta, sentinel, adjacentMeta.SideFromParent, adjacentMeta.Sibling)); } else { return(SwapWithAdjacent(adjacentMeta, side)); } }