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));
            }
        }
示例#2
0
        /// <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));
            }
        }