Exemplo n.º 1
0
        private void SearchSubtree(IntervalNode <TKey, TValue> node, Interval <TKey> i, List <KeyValuePair <Interval <TKey>, TValue> > result)
        {
            if (node == Sentinel)
            {
                return;
            }

            if (node.Left != Sentinel)
            {
                SearchSubtree(node.Left, i, result);
            }

            if (i.Overlaps(node.Interval))
            {
                foreach (var v in node.Values)
                {
                    result.Add(new KeyValuePair <Interval <TKey>, TValue>(node.Interval, v));
                }
            }

            // Interval start is greater than largest endpoint in this subtree
            if (node.Right != Sentinel && i.Start.CompareTo(node.MaxEnd) <= 0)
            {
                SearchSubtree(node.Right, i, result);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// General left rotation
        /// </summary>
        /// <param name="node">top of rotated subtree</param>
        private void RotateLeft(IntervalNode <TKey, TValue> node)
        {
            var           pivot    = node.Right;
            NodeDirection dir      = node.ParentDirection;
            var           parent   = node.Parent;
            var           tempTree = pivot.Left;

            pivot.Left  = node;
            node.Parent = pivot;
            node.Right  = tempTree;
            if (tempTree != Sentinel)
            {
                tempTree.Parent = node;
            }

            if (dir == NodeDirection.LEFT)
            {
                parent.Right = pivot;
            }
            else if (dir == NodeDirection.RIGHT)
            {
                parent.Left = pivot;
            }
            else
            {
                Root = pivot;
            }

            pivot.Parent = parent;

            pivot.RecalculateMaxEnd();
            node.RecalculateMaxEnd();
        }
Exemplo n.º 3
0
 public IntervalTree()
 {
     Root        = Sentinel;
     Root.Left   = Sentinel;
     Root.Right  = Sentinel;
     Root.Parent = Sentinel;
 }
Exemplo n.º 4
0
        private IntervalNode <TKey, TValue> FindInterval(IntervalNode <TKey, TValue> tree, Interval <TKey> i)
        {
            while (tree != Sentinel)
            {
                if (tree.Interval.CompareTo(i) > 0)
                {
                    tree = tree.Left;
                    continue;
                }

                if (tree.Interval.CompareTo(i) < 0)
                {
                    tree = tree.Right;
                    continue;
                }

                if (tree.Interval.CompareTo(i) == 0)
                {
                    return(tree);
                }
            }


            return(Sentinel);
        }
Exemplo n.º 5
0
        private void RemoveNode(IntervalNode <TKey, TValue> node)
        {
            if (node == Sentinel)
            {
                return;
            }

            IntervalNode <TKey, TValue> temp = node;

            if (node.Right != Sentinel && node.Left != Sentinel)
            {
                // Trick when deleting node with both children, switch it with closest in order node
                // swap values and delete the bottom node converting it to other cases

                temp          = node.GetSuccessor();
                node.Interval = temp.Interval;

                node.RecalculateMaxEnd();
                while (node.Parent != Sentinel)
                {
                    node = node.Parent;
                    node.RecalculateMaxEnd();
                }
            }
            node = temp;
            temp = node.Left != Sentinel ? node.Left : node.Right;

            // we will replace node with temp and delete node
            temp.Parent = node.Parent;
            if (node.IsRoot)
            {
                Root = temp; // Set new root
            }
            else
            {
                // Reattach node to parent
                if (node.ParentDirection == NodeDirection.RIGHT)
                {
                    node.Parent.Left = temp;
                }
                else
                {
                    node.Parent.Right = temp;
                }

                IntervalNode <TKey, TValue> maxAux = node.Parent;
                maxAux.RecalculateMaxEnd();
                while (maxAux.Parent != Sentinel)
                {
                    maxAux = maxAux.Parent;
                    maxAux.RecalculateMaxEnd();
                }
            }

            if (node.Color == NodeColor.BLACK)
            {
                RenewConstraintsAfterDelete(temp);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Validates and applies RB-tree constaints to node
        /// </summary>
        /// <param name="node">node to be validated and fixed</param>
        private void RenewConstraintsAfterInsert(IntervalNode <TKey, TValue> node)
        {
            if (node.Parent == Sentinel)
            {
                return;
            }

            if (node.Parent.Color == NodeColor.BLACK)
            {
                return;
            }

            var uncle = node.Uncle;

            if (uncle != Sentinel && uncle.Color == NodeColor.RED)
            {
                node.Parent.Color = uncle.Color = NodeColor.BLACK;

                var gparent = node.GrandParent;
                if (gparent != Sentinel && !gparent.IsRoot)
                {
                    gparent.Color = NodeColor.RED;
                    RenewConstraintsAfterInsert(gparent);
                }
            }
            else
            {
                if (node.ParentDirection == NodeDirection.LEFT && node.Parent.ParentDirection == NodeDirection.RIGHT)
                {
                    RotateLeft(node.Parent);
                    node = node.Left;
                }
                else if (node.ParentDirection == NodeDirection.RIGHT && node.Parent.ParentDirection == NodeDirection.LEFT)
                {
                    RotateRight(node.Parent);
                    node = node.Right;
                }

                node.Parent.Color = NodeColor.BLACK;

                if (node.GrandParent == Sentinel)
                {
                    return;
                }
                node.GrandParent.Color = NodeColor.RED;

                if (node.ParentDirection == NodeDirection.RIGHT)
                {
                    RotateRight(node.GrandParent);
                }
                else
                {
                    RotateLeft(node.GrandParent);
                }
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Insert new interval to interval tree
 /// </summary>
 /// <param name="interval">interval to add</param>
 public void Add(Interval <TKey> interval, TValue value)
 {
     if (Root == Sentinel)
     {
         var node = new IntervalNode <TKey, TValue>(interval, value);
         node.Color = NodeColor.BLACK;
         Root       = node;
     }
     else
     {
         InsertInterval(interval, value, Root);
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Recursively descends to the correct spot for interval insertion in the tree
        /// When a free spot is found for the node, it is attached and tree state is validated
        /// </summary>
        /// <param name="interval">interval to be added</param>
        /// <param name="currentNode">subtree accessed in recursion</param>
        private void InsertInterval(Interval <TKey> interval, TValue value, IntervalNode <TKey, TValue> currentNode)
        {
            IntervalNode <TKey, TValue> addedNode = Sentinel;

            if (interval.CompareTo(currentNode.Interval) < 0)
            {
                if (currentNode.Left == Sentinel)
                {
                    addedNode        = new IntervalNode <TKey, TValue>(interval, value);
                    addedNode.Color  = NodeColor.RED;
                    currentNode.Left = addedNode;
                    addedNode.Parent = currentNode;
                }
                else
                {
                    InsertInterval(interval, value, currentNode.Left);
                    return;
                }
            }
            else if (interval.CompareTo(currentNode.Interval) > 0)
            {
                if (currentNode.Right == Sentinel)
                {
                    addedNode         = new IntervalNode <TKey, TValue>(interval, value);
                    addedNode.Color   = NodeColor.RED;
                    currentNode.Right = addedNode;
                    addedNode.Parent  = currentNode;
                }
                else
                {
                    InsertInterval(interval, value, currentNode.Right);
                    return;
                }
            }
            else
            {
                currentNode.Values.AddFirst(value);
                return;
            }

            addedNode.Parent.RecalculateMaxEnd();

            RenewConstraintsAfterInsert(addedNode);

            Root.Color = NodeColor.BLACK;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Recursively descends down the tree and adds valids results to the resultset
        /// </summary>
        /// <param name="node">subtree to be searched</param>
        /// <param name="val">value to be searched for</param>
        /// <param name="result">current resultset</param>
        private void SearchSubtree(IntervalNode <TKey, TValue> node, TKey val, List <KeyValuePair <Interval <TKey>, TValue> > result)
        {
            if (node == Sentinel)
            {
                return;
            }

            // Value is higher than any interval in this subtree
            if (val.CompareTo(node.MaxEnd) > 0)
            {
                return;
            }

            if (node.Left != Sentinel)
            {
                SearchSubtree(node.Left, val, result);
            }

            if (node.Interval.Contains(val))
            {
                foreach (var v in node.Values)
                {
                    result.Add(new KeyValuePair <Interval <TKey>, TValue>(node.Interval, v));
                }
            }

            if (val.CompareTo(node.Interval.Start) < 0)
            {
                return;
            }

            if (node.Right != Sentinel)
            {
                SearchSubtree(node.Right, val, result);
            }
        }
Exemplo n.º 10
0
        private IEnumerable <KeyValuePair <Interval <TKey>, IEnumerable <TValue> > > InOrderWalk(IntervalNode <TKey, TValue> node)
        {
            if (node.Left != Sentinel)
            {
                foreach (var val in InOrderWalk(node.Left))
                {
                    yield return(val);
                }
            }

            if (node != Sentinel)
            {
                yield return(new KeyValuePair <Interval <TKey>, IEnumerable <TValue> >(node.Interval, node.Values));
            }

            if (node.Right != Sentinel)
            {
                foreach (var val in InOrderWalk(node.Right))
                {
                    yield return(val);
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Ensures constraints still apply after node deletion
        ///
        ///  - made with the help of algorithm from Cormen et Al. Introduction to Algorithms 2nd ed.
        /// </summary>
        /// <param name="node"></param>
        private void RenewConstraintsAfterDelete(IntervalNode <TKey, TValue> node)
        {
            // Need to bubble up and fix
            while (node != Root && node.Color == NodeColor.BLACK)
            {
                if (node.ParentDirection == NodeDirection.RIGHT)
                {
                    IntervalNode <TKey, TValue> aux = node.Parent.Right;
                    if (aux.Color == NodeColor.RED)
                    {
                        aux.Color         = NodeColor.BLACK;
                        node.Parent.Color = NodeColor.RED;
                        RotateLeft(node.Parent);
                        aux = node.Parent.Right;
                    }

                    if (aux.Left.Color == NodeColor.BLACK && aux.Right.Color == NodeColor.BLACK)
                    {
                        aux.Color = NodeColor.RED;
                        node      = node.Parent;
                    }
                    else
                    {
                        if (aux.Right.Color == NodeColor.BLACK)
                        {
                            aux.Left.Color = NodeColor.BLACK;
                            aux.Color      = NodeColor.RED;
                            RotateRight(aux);
                            aux = node.Parent.Right;
                        }

                        aux.Color         = node.Parent.Color;
                        node.Parent.Color = NodeColor.BLACK;
                        aux.Right.Color   = NodeColor.BLACK;
                        RotateLeft(node.Parent);
                        node = Root;
                    }
                }
                else
                {
                    IntervalNode <TKey, TValue> aux = node.Parent.Left;
                    if (aux.Color == NodeColor.RED)
                    {
                        aux.Color         = NodeColor.BLACK;
                        node.Parent.Color = NodeColor.RED;
                        RotateRight(node.Parent);
                        aux = node.Parent.Left;
                    }

                    if (aux.Left.Color == NodeColor.BLACK && aux.Right.Color == NodeColor.BLACK)
                    {
                        aux.Color = NodeColor.RED;
                        node      = node.Parent;
                    }
                    else
                    {
                        if (aux.Left.Color == NodeColor.BLACK)
                        {
                            aux.Right.Color = NodeColor.BLACK;
                            aux.Color       = NodeColor.RED;
                            RotateLeft(aux);
                            aux = node.Parent.Left;
                        }

                        aux.Color         = node.Parent.Color;
                        node.Parent.Color = NodeColor.BLACK;
                        aux.Left.Color    = NodeColor.BLACK;
                        RotateRight(node.Parent);
                        node = Root;
                    }
                }
            }

            node.Color = NodeColor.BLACK;
        }
Exemplo n.º 12
0
 public int CompareTo(IntervalNode <TKey, TValue> other)
 {
     return(Interval.CompareTo(other.Interval));
 }