Ejemplo n.º 1
0
            // <summary>Return number of nodes of current sub-tree containing
            // element. Uses IComparer <paramref name='cmp '/> to find and to
            // check equality.</summary>
            // <param name='element'></param>
            // <param name='cmp'>An IComparer object.</param>
            // <returns>A 32-bit signed integer.</returns>
            public int count(T element, IComparer <T> cmp)
            {
                var    c = 0;
                RBCell t = this;

                while (t != null)
                {
                    int diff = cmp.Compare(element, t.element());
                    if (diff == 0)
                    {
                        ++c;
                        if (t.leftValue == null)
                        {
                            t = t.rightValue;
                        }
                        else if (t.rightValue == null)
                        {
                            t = t.leftValue;
                        }
                        else
                        {
                            c += t.rightValue.count(element, cmp);
                            t  = t.leftValue;
                        }
                    }
                    else
                    {
                        t = (diff < 0) ? t.leftValue : t.rightValue;
                    }
                }
                return(c);
            }
Ejemplo n.º 2
0
            /** From CLR **/ private RBCell rotateLeft(RBCell rootValue)
            {
                RBCell r = this.rightValue;

                this.rightValue = r.leftValue;
                if (r.leftValue != null)
                {
                    r.leftValue.parentValue = this;
                }
                r.parentValue = this.parentValue;
                if (this.parentValue == null)
                {
                    rootValue = r;
                }
                else if (this.parentValue.leftValue == this)
                {
                    this.parentValue.leftValue = r;
                }
                else
                {
                    this.parentValue.rightValue = r;
                }
                r.leftValue      = this;
                this.parentValue = r;
                return(rootValue);
            }
Ejemplo n.º 3
0
 // <summary>Set the color of node p, or do nothing if p is
 // null.</summary>
 // <param name='p'></param>
 // <param name='c'>A Boolean object.</param>
 private static void setColor(RBCell p, bool c)
 {
     if (p != null)
     {
         p.colorValue = c;
     }
 }
Ejemplo n.º 4
0
            /** From CLR **/ private RBCell rotateRight(RBCell rootValue)
            {
                RBCell l = this.leftValue;

                this.leftValue = l.rightValue;
                if (l.rightValue != null)
                {
                    l.rightValue.parentValue = this;
                }
                l.parentValue = this.parentValue;
                if (this.parentValue == null)
                {
                    rootValue = l;
                }
                else if (this.parentValue.rightValue == this)
                {
                    this.parentValue.rightValue = l;
                }
                else
                {
                    this.parentValue.leftValue = l;
                }
                l.rightValue     = this;
                this.parentValue = l;
                return(rootValue);
            }
Ejemplo n.º 5
0
 // <summary>Copies this object's data to a new array.</summary>
 // <param name='array'>A T[] object.</param>
 // <param name='arrayIndex'>Starting index to copy to.</param>
 public void CopyTo(T[] array, int arrayIndex)
 {
     if (array == null)
     {
         throw new ArgumentNullException("array");
     }
     if (arrayIndex < 0)
     {
         throw new ArgumentException("arrayIndex (" + arrayIndex +
                                     ") is less than 0");
     }
     if (this.treeValue != null)
     {
         RBCell t = this.treeValue.leftmost();
         while (t != null && arrayIndex < array.Length)
         {
             T v = t.element();
             if (arrayIndex >= 0 && arrayIndex < array.Length)
             {
                 array[arrayIndex] = v;
             }
             ++arrayIndex;
             t = t.successor();
         }
     }
 }
Ejemplo n.º 6
0
            // <summary>Return the minimum element of the current
            // (sub)tree.</summary>
            // <returns>A RBCell object.</returns>
            public RBCell leftmost()
            {
                RBCell p = this;

                for (; p.leftValue != null; p = p.leftValue)
                {
                }
                return(p);
            }
Ejemplo n.º 7
0
            // <summary>Return the root (parentless node) of the tree.</summary>
            // <returns>A RBCell object.</returns>
            public RBCell root()
            {
                RBCell p = this;

                for (; p.parentValue != null; p = p.parentValue)
                {
                }
                return(p);
            }
Ejemplo n.º 8
0
            // <summary>Return the maximum element of the current
            // (sub)tree.</summary>
            // <returns>A RBCell object.</returns>
            public RBCell rightmost()
            {
                RBCell p = this;

                for (; p.rightValue != null; p = p.rightValue)
                {
                }
                return(p);
            }
Ejemplo n.º 9
0
 // helper methods
 private bool addInternal(T element, OccurrenceMode checkOccurrence)
 {
     if (this.treeValue == null)
     {
         this.treeValue = new RBCell(element);
         this.incCount();
     }
     else
     {
         RBCell t = this.treeValue;
         for (;;)
         {
             int diff = this.cmpValue.Compare(element, t.element());
             if (diff == 0 && checkOccurrence == OccurrenceMode.AddIfMissing)
             {
                 return(false);
             }
             if (diff == 0 && checkOccurrence == OccurrenceMode.OverwriteIfExisting)
             {
                 t.element(element);
                 return(false);
             }
             if (diff <= 0)
             {
                 if (t.left() != null)
                 {
                     t = t.left();
                 }
                 else
                 {
                     this.treeValue = t.insertLeft(
                         new RBCell(element),
                         this.treeValue);
                     this.incCount();
                     return(true);
                 }
             }
             else
             {
                 if (t.right() != null)
                 {
                     t = t.right();
                 }
                 else
                 {
                     this.treeValue = t.insertRight(
                         new RBCell(element),
                         this.treeValue);
                     this.incCount();
                     return(true);
                 }
             }
         }
     }
     return(true);
 }
Ejemplo n.º 10
0
 // <summary>Implements collections.UpdatableCollection.take. Time
 // complexity: O(log n). Takes the least element. @see
 // collections.UpdatableCollection#take.</summary>
 // <returns>A T object.</returns>
 public T Pop()
 {
     if (this.countValue != 0)
     {
         RBCell p = this.treeValue.leftmost();
         T      v = p.element();
         this.treeValue = p.delete(this.treeValue);
         this.decCount();
         return(v);
     }
     return(default(T));
 }
Ejemplo n.º 11
0
        private IEnumerable <T> Iterator()
        {
            if (this.treeValue != null)
            {
                RBCell t = this.treeValue.leftmost();
                while (t != null)
                {
                    T v = t.element();
                    yield return(v);

                    t = t.successor();
                }
            }
        }
Ejemplo n.º 12
0
        public bool Find(T element, out T outval)
        {
            if (this.countValue == 0)
            {
                outval = default(T);
                return(false);
            }
            RBCell cell = this.treeValue.find(element, this.cmpValue);

            if (cell == null)
            {
                outval = default(T);
                return(false);
            }
            outval = cell.element();
            return(true);
        }
Ejemplo n.º 13
0
            // <summary>Return node of current sub-tree containing element as
            // element(), if it exists, else null. Uses IComparer <paramref
            // name='cmp '/> to find and to check equality.</summary>
            // <param name='element'></param>
            // <param name='cmp'>An IComparer object.</param>
            // <returns>A RBCell object.</returns>
            public RBCell find(T element, IComparer <T> cmp)
            {
                RBCell t = this;

                for (;;)
                {
                    int diff = cmp.Compare(element, t.element());
                    if (diff == 0)
                    {
                        return(t);
                    }
                    t = (diff < 0) ? t.leftValue : t.rightValue;
                    if (t == null)
                    {
                        return(null);
                    }
                }
            }
Ejemplo n.º 14
0
 // <summary>Return the in-order predecessor, or null if no
 // such.</summary>
 // <returns>A RBCell object.</returns>
 public RBCell predecessor()
 {
     if (this.leftValue != null)
     {
         return(this.leftValue.rightmost());
     }
     else
     {
         RBCell p  = this.parentValue;
         RBCell ch = this;
         while (p != null && ch == p.leftValue)
         {
             {
                 ch = p;
             }
             p = p.parentValue;
         }
         return(p);
     }
 }
Ejemplo n.º 15
0
        private bool remove_(T element, bool allOccurrences)
        {
            var ret = false;

            while (this.countValue > 0)
            {
                RBCell p = this.treeValue.find(element, this.cmpValue);
                if (p != null)
                {
                    this.treeValue = p.delete(this.treeValue);
                    this.decCount();
                    ret = true;
                    if (!allOccurrences)
                    {
                        return(ret);
                    }
                }
                else
                {
                    break;
                }
            }
            return(ret);
        }
Ejemplo n.º 16
0
            /** From CLR **/ private RBCell fixAfterInsertion(RBCell rootValue)
            {
                this.colorValue = RED;
                RBCell x = this;

                while (x != null && x != rootValue && !x.parentValue.colorValue)
                {
                    if (parentOf(x) == leftOf(parentOf(parentOf(x))))
                    {
                        RBCell y = rightOf(parentOf(parentOf(x)));
                        if (!colorOf(y))
                        {
                            setColor(parentOf(x), BLACK);
                            setColor(y, BLACK);
                            setColor(parentOf(parentOf(x)), RED);
                            x = parentOf(parentOf(x));
                        }
                        else
                        {
                            if (x == rightOf(parentOf(x)))
                            {
                                x         = parentOf(x);
                                rootValue = x.rotateLeft(rootValue);
                            }
                            setColor(parentOf(x), BLACK);
                            setColor(parentOf(parentOf(x)), RED);
                            if (parentOf(parentOf(x)) != null)
                            {
                                rootValue = parentOf(parentOf(x)).rotateRight(rootValue);
                            }
                        }
                    }
                    else
                    {
                        RBCell y = leftOf(parentOf(parentOf(x)));
                        if (!colorOf(y))
                        {
                            setColor(parentOf(x), BLACK);
                            setColor(y, BLACK);
                            setColor(parentOf(parentOf(x)), RED);
                            x = parentOf(parentOf(x));
                        }
                        else
                        {
                            if (x == leftOf(parentOf(x)))
                            {
                                x         = parentOf(x);
                                rootValue = x.rotateRight(rootValue);
                            }
                            setColor(parentOf(x), BLACK);
                            setColor(parentOf(parentOf(x)), RED);
                            if (parentOf(parentOf(x)) != null)
                            {
                                rootValue = parentOf(parentOf(x)).rotateLeft(rootValue);
                            }
                        }
                    }
                }
                rootValue.colorValue = BLACK;
                return(rootValue);
            }
Ejemplo n.º 17
0
 // <summary>Return left child of node p, or null if p is
 // null.</summary>
 // <param name='p'></param>
 // <returns>A RBCell object.</returns>
 private static RBCell leftOf(RBCell p)
 {
     return((p == null) ? null : p.leftValue);
 }
Ejemplo n.º 18
0
 // <summary>Insert cell as the right child of current node, and then
 // rebalance the tree it is in.</summary>
 // <param name='cell'>The cell to add.</param>
 // <param name='root'>The root of the current tree.</param>
 // <returns>The new root of the current tree. (Rebalancing can change
 // the root!).</returns>
 public RBCell insertRight(RBCell cell, RBCell root)
 {
     this.rightValue  = cell;
     cell.parentValue = this;
     return(cell.fixAfterInsertion(root));
 }
Ejemplo n.º 19
0
            // <summary>Delete the current node, and then rebalance the tree it is
            // in.</summary>
            // <param name='root'>The root of the current tree.</param>
            // <returns>The new root of the current tree. Rebalancing can change
            // the root.</returns>
            public RBCell delete(RBCell root)
            {
                // if strictly internal, swap contents with successor and then delete it
                if (this.leftValue != null && this.rightValue != null)
                {
                    RBCell s = this.successor();
                    this.copyContents(s);
                    return(s.delete(root));
                }
                // Start fixup at replacement node, if it exists
                RBCell replacement = this.leftValue ?? this.rightValue;

                if (replacement != null)
                {
                    // link replacement to parent
                    replacement.parentValue = this.parentValue;
                    if (this.parentValue == null)
                    {
                        root = replacement;
                    }
                    else if (this == this.parentValue.leftValue)
                    {
                        this.parentValue.leftValue = replacement;
                    }
                    else
                    {
                        this.parentValue.rightValue = replacement;
                    }
                    // null out links so they are OK to use by fixAfterDeletion
                    this.leftValue   = null;
                    this.rightValue  = null;
                    this.parentValue = null;
                    // fix replacement
                    if (this.colorValue)
                    {
                        root = replacement.fixAfterDeletion(root);
                    }
                    return(root);
                }
                if (this.parentValue == null) // exit if we are the only node
                // if no children, use self as phantom replacement
                // and then unlink
                {
                    return(null);
                }
                if (this.colorValue)
                {
                    root = this.fixAfterDeletion(root);
                }
                // Unlink (Couldn't before since fixAfterDeletion needs parent ptr)
                if (this.parentValue != null)
                {
                    if (this == this.parentValue.leftValue)
                    {
                        this.parentValue.leftValue = null;
                    }
                    else if (this == this.parentValue.rightValue)
                    {
                        this.parentValue.rightValue = null;
                    }
                    this.parentValue = null;
                }
                return(root);
            }
Ejemplo n.º 20
0
 // <summary>Return right child of node p, or null if p is
 // null.</summary>
 // <param name='p'></param>
 // <returns>A RBCell object.</returns>
 private static RBCell rightOf(RBCell p)
 {
     return((p == null) ? null : p.rightValue);
 }
Ejemplo n.º 21
0
 // <summary>Copy all content fields from another node.</summary>
 // <param name='t'></param>
 private void copyContents(RBCell t)
 {
     this.elementValue = t.elementValue;
 }
Ejemplo n.º 22
0
 // <summary>Return parent of node p, or null if p is null.</summary>
 // <param name='p'></param>
 // <returns>A RBCell object.</returns>
 private static RBCell parentOf(RBCell p)
 {
     return((p == null) ? null : p.parentValue);
 }
Ejemplo n.º 23
0
            /** From CLR **/
            private RBCell fixAfterDeletion(RBCell rootValue)
            {
                RBCell x = this;

                while (x != rootValue && colorOf(x))
                {
                    if (x == leftOf(parentOf(x)))
                    {
                        RBCell sib = rightOf(parentOf(x));
                        if (!colorOf(sib))
                        {
                            setColor(sib, BLACK);
                            setColor(parentOf(x), RED);
                            rootValue = parentOf(x).rotateLeft(rootValue);
                            sib       = rightOf(parentOf(x));
                        }
                        if (colorOf(leftOf(sib)) && colorOf(rightOf(sib)))
                        {
                            setColor(sib, RED);
                            x = parentOf(x);
                        }
                        else
                        {
                            if (colorOf(rightOf(sib)))
                            {
                                setColor(leftOf(sib), BLACK);
                                setColor(sib, RED);
                                rootValue = sib.rotateRight(rootValue);
                                sib       = rightOf(parentOf(x));
                            }
                            setColor(sib, colorOf(parentOf(x)));
                            setColor(parentOf(x), BLACK);
                            setColor(rightOf(sib), BLACK);
                            rootValue = parentOf(x).rotateLeft(rootValue);
                            x         = rootValue;
                        }
                    }
                    else // symmetric
                    {
                        RBCell sib = leftOf(parentOf(x));
                        if (!colorOf(sib))
                        {
                            setColor(sib, BLACK);
                            setColor(parentOf(x), RED);
                            rootValue = parentOf(x).rotateRight(rootValue);
                            sib       = leftOf(parentOf(x));
                        }
                        if (colorOf(rightOf(sib)) && colorOf(leftOf(sib)))
                        {
                            setColor(sib, RED);
                            x = parentOf(x);
                        }
                        else
                        {
                            if (colorOf(leftOf(sib)))
                            {
                                setColor(rightOf(sib), BLACK);
                                setColor(sib, RED);
                                rootValue = sib.rotateLeft(rootValue);
                                sib       = leftOf(parentOf(x));
                            }
                            setColor(sib, colorOf(parentOf(x)));
                            setColor(parentOf(x), BLACK);
                            setColor(leftOf(sib), BLACK);
                            rootValue = parentOf(x).rotateRight(rootValue);
                            x         = rootValue;
                        }
                    }
                }
                setColor(x, BLACK);
                return(rootValue);
            }
Ejemplo n.º 24
0
 // <summary>Initializes a new instance of the RedBlackTree class.
 // Special version of constructor needed by clone().</summary>
 // <param name='cmp'>An IComparer object.</param>
 // <param name='t'>A RBCell object.</param>
 // <param name='n'>A 32-bit signed integer.</param>
 private RedBlackTree(IComparer <T> cmp, RBCell t, int n)
 {
     this.countValue = n;
     this.treeValue  = t;
     this.cmpValue   = cmp ?? Comparer <T> .Default;
 }
Ejemplo n.º 25
0
 // <summary>Implements collections.UpdatableCollection.clear. Time
 // complexity: O(1). @see
 // collections.UpdatableCollection#clear.</summary>
 public void Clear()
 {
     this.countValue = 0;
     this.treeValue  = null;
 }
Ejemplo n.º 26
0
 // <summary>Return color of node p, or BLACK if p is null.</summary>
 // <param name='p'></param>
 // <returns>A Boolean object.</returns>
 private static bool colorOf(RBCell p)
 {
     return((p == null) ? BLACK : p.colorValue);
 }