Пример #1
0
 /// <summary>
 /// Checks if current node is in search range.
 /// </summary>
 private bool inRange(RedBlackTreeNode <RangeTreeNode <T> > currentNode, T start, T end)
 {
     //start is less than current and end is greater than current
     return(start.CompareTo(currentNode.Value.Value) <= 0 &&
            end.CompareTo(currentNode.Value.Value) >= 0);
 }
Пример #2
0
 private RedBlackTreeNode <T> findMax(RedBlackTreeNode <T> node)
 {
     return(node.FindMax() as RedBlackTreeNode <T>);
 }
Пример #3
0
 internal RedBlackTreeNode(RedBlackTreeNode <T> parent, T value)
 {
     Parent    = parent;
     Value     = value;
     NodeColor = RedBlackTreeNodeColor.Red;
 }
Пример #4
0
 /// <summary>
 ///  Time complexity: O(1)
 /// </summary>
 internal void Clear()
 {
     Root = null;
 }
Пример #5
0
        private RedBlackTreeNode <T> handleDoubleBlack(RedBlackTreeNode <T> node)
        {
            //case 1
            if (node == Root)
            {
                node.NodeColor = RedBlackTreeNodeColor.Black;
                return(null);
            }

            //case 2
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Red &&
                ((node.Sibling.Left == null && node.Sibling.Right == null) ||
                 (node.Sibling.Left != null && node.Sibling.Right != null &&
                  node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Black &&
                  node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Black)))
            {
                node.Parent.NodeColor  = RedBlackTreeNodeColor.Red;
                node.Sibling.NodeColor = RedBlackTreeNodeColor.Black;

                if (node.Sibling.IsRightChild)
                {
                    leftRotate(node.Parent);
                }
                else
                {
                    rightRotate(node.Parent);
                }

                return(node);
            }
            //case 3
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                (node.Sibling.Left == null && node.Sibling.Right == null ||
                 node.Sibling.Left != null && node.Sibling.Right != null &&
                 node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Black &&
                 node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Black))
            {
                //pushed up the double black problem up to parent
                //so now it needs to be fixed
                node.Sibling.NodeColor = RedBlackTreeNodeColor.Red;

                return(node.Parent);
            }


            //case 4
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Red &&
                node.Sibling != null &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                (node.Sibling.Left == null && node.Sibling.Right == null ||
                 node.Sibling.Left != null && node.Sibling.Right != null &&
                 node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Black &&
                 node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Black))
            {
                //just swap the color of parent and sibling
                //which will compensate the loss of black count
                node.Parent.NodeColor  = RedBlackTreeNodeColor.Black;
                node.Sibling.NodeColor = RedBlackTreeNodeColor.Red;
                node.UpdateCounts(true);
                return(null);
            }


            //case 5
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.IsRightChild &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling.Left != null &&
                node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Red &&
                node.Sibling.Right != null &&
                node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Black)
            {
                node.Sibling.NodeColor      = RedBlackTreeNodeColor.Red;
                node.Sibling.Left.NodeColor = RedBlackTreeNodeColor.Black;
                rightRotate(node.Sibling);

                return(node);
            }

            //case 5 mirror
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.IsLeftChild &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling.Left != null &&
                node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling.Right != null &&
                node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Red)
            {
                node.Sibling.NodeColor       = RedBlackTreeNodeColor.Red;
                node.Sibling.Right.NodeColor = RedBlackTreeNodeColor.Black;
                leftRotate(node.Sibling);

                return(node);
            }

            //case 6
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.IsRightChild &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling.Right != null &&
                node.Sibling.Right.NodeColor == RedBlackTreeNodeColor.Red)
            {
                //left rotate to increase the black count on left side by one
                //and mark the red right child of sibling to black
                //to compensate the loss of Black on right side of parent
                node.Sibling.Right.NodeColor = RedBlackTreeNodeColor.Black;
                leftRotate(node.Parent);
                node.UpdateCounts(true);
                return(null);
            }

            //case 6 mirror
            if (node.Parent != null &&
                node.Parent.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling != null &&
                node.Sibling.IsLeftChild &&
                node.Sibling.NodeColor == RedBlackTreeNodeColor.Black &&
                node.Sibling.Left != null &&
                node.Sibling.Left.NodeColor == RedBlackTreeNodeColor.Red)
            {
                //right rotate to increase the black count on right side by one
                //and mark the red left child of sibling to black
                //to compensate the loss of Black on right side of parent
                node.Sibling.Left.NodeColor = RedBlackTreeNodeColor.Black;
                rightRotate(node.Parent);
                node.UpdateCounts(true);
                return(null);
            }

            node.UpdateCounts(true);
            return(null);
        }
Пример #6
0
        private void balanceInsertion(RedBlackTreeNode <T> nodeToBalance)
        {
            while (true)
            {
                if (nodeToBalance == Root)
                {
                    nodeToBalance.NodeColor = RedBlackTreeNodeColor.Black;
                    break;
                }

                //if node to balance is red
                if (nodeToBalance.NodeColor == RedBlackTreeNodeColor.Red)
                {
                    //red-red relation; fix it!
                    if (nodeToBalance.Parent.NodeColor == RedBlackTreeNodeColor.Red)
                    {
                        //red sibling
                        if (nodeToBalance.Parent.Sibling != null && nodeToBalance.Parent.Sibling.NodeColor == RedBlackTreeNodeColor.Red)
                        {
                            //mark both children of parent as black and move up balancing
                            nodeToBalance.Parent.Sibling.NodeColor = RedBlackTreeNodeColor.Black;
                            nodeToBalance.Parent.NodeColor         = RedBlackTreeNodeColor.Black;

                            //root is always black
                            if (nodeToBalance.Parent.Parent != Root)
                            {
                                nodeToBalance.Parent.Parent.NodeColor = RedBlackTreeNodeColor.Red;
                            }

                            nodeToBalance.UpdateCounts();
                            nodeToBalance.Parent.UpdateCounts();
                            nodeToBalance = nodeToBalance.Parent.Parent;
                        }
                        //absent sibling or black sibling
                        else if (nodeToBalance.Parent.Sibling == null || nodeToBalance.Parent.Sibling.NodeColor == RedBlackTreeNodeColor.Black)
                        {
                            if (nodeToBalance.IsLeftChild && nodeToBalance.Parent.IsLeftChild)
                            {
                                var newRoot = nodeToBalance.Parent;
                                swapColors(nodeToBalance.Parent, nodeToBalance.Parent.Parent);
                                rightRotate(nodeToBalance.Parent.Parent);

                                if (newRoot == Root)
                                {
                                    Root.NodeColor = RedBlackTreeNodeColor.Black;
                                }

                                nodeToBalance.UpdateCounts();
                                nodeToBalance = newRoot;
                            }
                            else if (nodeToBalance.IsLeftChild && nodeToBalance.Parent.IsRightChild)
                            {
                                rightRotate(nodeToBalance.Parent);

                                var newRoot = nodeToBalance;

                                swapColors(nodeToBalance.Parent, nodeToBalance);
                                leftRotate(nodeToBalance.Parent);

                                if (newRoot == Root)
                                {
                                    Root.NodeColor = RedBlackTreeNodeColor.Black;
                                }

                                nodeToBalance.UpdateCounts();
                                nodeToBalance = newRoot;
                            }
                            else if (nodeToBalance.IsRightChild && nodeToBalance.Parent.IsRightChild)
                            {
                                var newRoot = nodeToBalance.Parent;
                                swapColors(nodeToBalance.Parent, nodeToBalance.Parent.Parent);
                                leftRotate(nodeToBalance.Parent.Parent);

                                if (newRoot == Root)
                                {
                                    Root.NodeColor = RedBlackTreeNodeColor.Black;
                                }

                                nodeToBalance.UpdateCounts();
                                nodeToBalance = newRoot;
                            }
                            else if (nodeToBalance.IsRightChild && nodeToBalance.Parent.IsLeftChild)
                            {
                                leftRotate(nodeToBalance.Parent);

                                var newRoot = nodeToBalance;

                                swapColors(nodeToBalance.Parent, nodeToBalance);
                                rightRotate(nodeToBalance.Parent);

                                if (newRoot == Root)
                                {
                                    Root.NodeColor = RedBlackTreeNodeColor.Black;
                                }

                                nodeToBalance.UpdateCounts();
                                nodeToBalance = newRoot;
                            }
                        }
                    }
                }

                if (nodeToBalance.Parent != null)
                {
                    nodeToBalance.UpdateCounts();
                    nodeToBalance = nodeToBalance.Parent;
                    continue;
                }

                break;
            }

            nodeToBalance.UpdateCounts(true);
        }
Пример #7
0
        //O(log(n)) always
        private void delete(RedBlackTreeNode <T> node, T value)
        {
            RedBlackTreeNode <T> nodeToBalance = null;

            var compareResult = node.Value.CompareTo(value);

            //node is less than the search value so move right to find the deletion node
            if (compareResult < 0)
            {
                if (node.Right == null)
                {
                    throw new Exception("Item do not exist");
                }

                delete(node.Right, value);
            }
            //node is less than the search value so move left to find the deletion node
            else if (compareResult > 0)
            {
                if (node.Left == null)
                {
                    throw new Exception("Item do not exist");
                }

                delete(node.Left, value);
            }
            else
            {
                //duplicate - easy fix
                if (node.Values.Count > 1)
                {
                    node.Values.RemoveAt(node.Values.Count - 1);
                    return;
                }

                //node is a leaf node
                if (node.IsLeaf)
                {
                    //if color is red, we are good; no need to balance
                    if (node.NodeColor == RedBlackTreeNodeColor.Red)
                    {
                        deleteLeaf(node);
                        return;
                    }

                    nodeToBalance = handleDoubleBlack(node);
                    deleteLeaf(node);
                }
                else
                {
                    //case one - right tree is null (move sub tree up)
                    if (node.Left != null && node.Right == null)
                    {
                        nodeToBalance = handleDoubleBlack(node);
                        deleteLeftNode(node);
                    }
                    //case two - left tree is null  (move sub tree up)
                    else if (node.Right != null && node.Left == null)
                    {
                        nodeToBalance = handleDoubleBlack(node);
                        deleteRightNode(node);
                    }
                    //case three - two child trees
                    //replace the node value with maximum element of left subtree (left max node)
                    //and then delete the left max node
                    else
                    {
                        var maxLeftNode = FindMax(node.Left);

                        node.Values.Clear();
                        node.Values.Add(maxLeftNode.Value);

                        //delete left max node
                        delete(node.Left, maxLeftNode.Value);
                    }
                }
            }


            //handle six cases
            while (nodeToBalance != null)
            {
                nodeToBalance = handleDoubleBlack(nodeToBalance);
            }
        }
        /// <summary>
        /// update max end value under each node in red-black tree recursively.
        /// </summary>
        private void updateMax(RedBlackTreeNode <OneDimentionalInterval <T> > node, T currentMax, bool recurseUp = true)
        {
            while (true)
            {
                if (node == null)
                {
                    return;
                }

                if (node.Left != null && node.Right != null)
                {
                    //if current Max is less than current End
                    //then update current Max
                    if (currentMax.CompareTo(node.Left.Value.MaxEnd) < 0)
                    {
                        currentMax = node.Left.Value.MaxEnd;
                    }

                    if (currentMax.CompareTo(node.Right.Value.MaxEnd) < 0)
                    {
                        currentMax = node.Right.Value.MaxEnd;
                    }
                }
                else if (node.Left != null)
                {
                    //if current Max is less than current End
                    //then update current Max
                    if (currentMax.CompareTo(node.Left.Value.MaxEnd) < 0)
                    {
                        currentMax = node.Left.Value.MaxEnd;
                    }
                }
                else if (node.Right != null)
                {
                    if (currentMax.CompareTo(node.Right.Value.MaxEnd) < 0)
                    {
                        currentMax = node.Right.Value.MaxEnd;
                    }
                }

                foreach (var v in node.Value.End)
                {
                    if (currentMax.CompareTo(v) < 0)
                    {
                        currentMax = v;
                    }
                }

                node.Value.MaxEnd = currentMax;


                if (recurseUp)
                {
                    node = node.Parent;
                    continue;
                }


                break;
            }
        }