Example #1
0
        public void AssertValidTree()
        {
            if (this.Root != null)
            {
                RedBlackNode <T> previousNode = null;
                foreach (RedBlackNode <T> node in this.InOrderNodeIterator)
                {
                    if (previousNode != null && previousNode.Value.CompareTo(node.Value) >= 0)
                    {
                        throw new InvalidTreeException();
                    }

                    previousNode = node;
                }
            }

            int numBlack;

            AssertValidTree(this.Root as RedBlackNode <T>, out numBlack);
        }
        public bool Contains(T item)
        {
            RedBlackNode <T> current = this.Root;

            while (current != null)
            {
                int compareResult = current.Value.CompareTo(item);
                if (compareResult == 0)
                {
                    break;
                }
                else if (compareResult > 0)
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }

            return(current != null);
        }
Example #3
0
        private static void AssertValidTree(RedBlackNode <T> root, out int numBlack)
        {
            if (root == null)
            {
                numBlack = 0;
            }
            else
            {
                if (IsNodeRed(root))
                {
                    if (IsNodeRed(root.Left) || IsNodeRed(root.Right))
                    {
                        throw new InvalidTreeException();
                    }
                }

                int leftBlack;
                int rightBlack;

                AssertValidTree(root.Left, out leftBlack);
                AssertValidTree(root.Right, out rightBlack);

                if (leftBlack != rightBlack)
                {
                    throw new InvalidTreeException();
                }

                if (IsNodeRed(root))
                {
                    numBlack = leftBlack;
                }
                else
                {
                    numBlack = leftBlack + 1;
                }
            }
        }
Example #4
0
        /// <summary>
        /// Inserts the given node underneath the given root according to the BinarySearchTree algorithm and then
        /// rebalances the tree according to the red-black tree rules
        /// </summary>
        /// <param name="root">The root node of the tree</param>
        /// <param name="node">The node to insert</param>
        /// <returns>The new root of the tree as it may have changed</returns>
        private RedBlackNode <T> Insert(RedBlackNode <T> root, RedBlackNode <T> node)
        {
            if (root == null)
            {
                root = node;
                ++this.Count;
            }
            else
            {
                root.ResetHeight();
                int compareResult = root.Value.CompareTo(node.Value);
                if (compareResult > 0)
                {
                    root.Left = Insert(root.Left, node);
                }
                else if (compareResult < 0)
                {
                    root.Right = Insert(root.Right, node);
                }
                else
                {
                    throw new ArgumentException("Insert duplicate");
                }
            }

            if (root.Value.CompareTo(node.Value) > 0)
            {
                root = Insert_Case1_LeftTwoRedChidren(root as RedBlackNode <T>);
            }
            else
            {
                root = Insert_Case1_RightTwoRedChidren(root as RedBlackNode <T>);
            }

            return(root);
        }
Example #5
0
 private int GetChildNodeHeight(RedBlackNode <T> node)
 {
     return((node == null) ? -1 : node.Height);
 }
Example #6
0
 /// <summary>
 /// Moves a black root node down to it's two children and colours the root red
 /// </summary>
 /// <param name="root"></param>
 private static void MoveBlackDown(RedBlackNode <T> root)
 {
     root.SetColour(Colour.Red);
     root.Left.SetColour(Colour.Black);
     root.Right.SetColour(Colour.Black);
 }
Example #7
0
 /// <summary>
 /// Returns true if the node is red. Returns false if the node is black or null.
 /// </summary>
 private static bool IsNodeRed(RedBlackNode <T> node)
 {
     return(node != null && node.IsRed);
 }
Example #8
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);
        }