Пример #1
0
        public void AssertValidTree()
        {
            if (Root != null)
            {
                RedBlackNode <T> previousNode = null;
                foreach (var node in InOrderNodeIterator)
                {
                    if (previousNode != null && previousNode.Value.CompareTo(node.Value) >= 0)
                    {
                        throw new MeshNavException("Invalid Red Black Tree");
                    }

                    previousNode = node;
                }
            }

            AssertValidTree(Root, out _);
        }
Пример #2
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.SetColor(Color.Red);
     root.Left.SetColor(Color.Black);
     root.Right.SetColor(Color.Black);
 }
Пример #3
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);
 }
Пример #4
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)
        {
            var compareResult = root.Value.CompareTo(value);

            if (compareResult == 0)
            {
                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)
                {
                    --Count;
                    root.Left.ResetHeight();
                    if (IsNodeRed(root.Left))                     // node to delete is black but has red child that can be recoloured
                    {
                        root.Left.SetColor(Color.Black);
                        done = true;
                    }

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

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

            // ReSharper disable PossibleNullReferenceException
            if (compareResult > 0)
            {
                if (root.Left != null)
                {
                    root.Left = Delete(root.Left, value, ref done);
                    if (!done)
                    {
                        root = DeleteRebalanceLeft(root, ref done);
                    }
                }
                else
                {
                    throw new MeshNavException("Value not found");
                }
            }
            else if (compareResult < 0)
            {
                if (root.Right != null)
                {
                    root.Right = Delete(root.Right, value, ref done);
                    if (!done)
                    {
                        root = DeleteRebalanceRight(root, ref done);
                    }
                }
                else
                {
                    throw new MeshNavException("Value not found");
                }
            }
            // ReSharper restore PossibleNullReferenceException

            return(root);
        }