Beispiel #1
0
        /// <summary>
        /// Rotates the tree rooted at this node in a clockwise manner and recolours the root and pivot nodes accordingly.
        /// </summary>
        /// <returns>The new root of the tree</returns>
        internal RedBlackNode <T> RotateRight()
        {
            RedBlackNode <T> pivot = this.Left;

            this.Left   = pivot.Right;
            pivot.Right = this;

            //fix heights
            pivot.ResetHeight();
            this.ResetHeight();

            pivot.Right.SetColour(Colour.Red);
            pivot.SetColour(Colour.Black);

            return(pivot);
        }
Beispiel #2
0
        /// <summary>
        /// Deletes the given value from the tree at the given root and ensures red-black tree properties are maintained ny recolouring nodes and rotations
        /// </summary>
        /// <param name="root">The root node of the tree</param>
        /// <param name="value">The value to delete</param>
        /// <param name="done">A flag determining if more rebalancing and recolouring is necessary</param>
        /// <returns>The new root of the tree as it may have changed</returns>
        private RedBlackNode <T> Delete(RedBlackNode <T> root, T value, ref bool done)
        {
            int compareResult = root.Value.CompareTo(value);

            if (compareResult == 0)
            {
                // Node has two children, replace with in order predecessor and then recursively delete predecessor
                if (root.Left != null && root.Right != null)
                {
                    compareResult = 1;
                    root.Value    = root.InOrderPredecessor.Value;
                    value         = root.Value;
                    root.ResetHeight();
                }
                // Node only has left child
                else if (root.Left != null)
                {
                    --this.Count;
                    root.Left.ResetHeight();
                    if (IsNodeRed(root.Left)) // node to delete is black but has red child that can be recoloured
                    {
                        root.Left.SetColour(Colour.Black);
                        done = true;
                    }

                    root = root.Left;
                }
                // Node only has Right child
                else if (root.Right != null)
                {
                    --this.Count;
                    root.Right.ResetHeight();
                    if (IsNodeRed(root.Right)) // node to delete is black but has red child that can be recoloured
                    {
                        root.Right.SetColour(Colour.Black);
                        done = true;
                    }

                    root = root.Right;
                }
                else // deleting leaf - done if red
                {
                    --this.Count;
                    done = IsNodeRed(root);
                    root = null;
                }
            }

            if (compareResult > 0)
            {
                if (root.Left != null)
                {
                    root.Left = Delete(root.Left, value, ref done);
                    if (!done)
                    {
                        root = this.DeleteRebalanceLeft(root, ref done);
                    }
                }
                else
                {
                    throw new ValueNotFoundException();
                }
            }
            else if (compareResult < 0)
            {
                if (root.Right != null)
                {
                    root.Right = Delete(root.Right, value, ref done);
                    if (!done)
                    {
                        root = this.DeleteRebalanceRight(root, ref done);
                    }
                }
                else
                {
                    throw new ValueNotFoundException();
                }
            }

            return(root);
        }