Ejemplo n.º 1
0
    public static void Main(String[] args)
    {
        SCG.IComparer <Rec <string, int> > lexico1 = new Lexico();
        SCG.IComparer <Rec <string, int> > lexico2 =
            new DelegateComparer <Rec <string, int> >(
                delegate(Rec <string, int> item1, Rec <string, int> item2) {
            int major = item1.X1.CompareTo(item2.X1);
            return(major != 0 ? major : item1.X2.CompareTo(item2.X2));
        });
        Rec <String, int> r1 = new Rec <String, int>("Carsten", 1962);
        Rec <String, int> r2 = new Rec <String, int>("Carsten", 1964);
        Rec <String, int> r3 = new Rec <String, int>("Christian", 1932);

        Console.WriteLine(lexico1.Compare(r1, r1) == 0);
        Console.WriteLine(lexico1.Compare(r1, r2) < 0);
        Console.WriteLine(lexico1.Compare(r2, r3) < 0);
        Console.WriteLine(lexico2.Compare(r1, r1) == 0);
        Console.WriteLine(lexico2.Compare(r1, r2) < 0);
        Console.WriteLine(lexico2.Compare(r2, r3) < 0);

        SCG.IComparer <String> rev
            = ReverseComparer <String>(Comparer <String> .Default);
        Console.WriteLine(rev.Compare("A", "A") == 0);
        Console.WriteLine(rev.Compare("A", "B") > 0);
        Console.WriteLine(rev.Compare("B", "A") < 0);
    }
Ejemplo n.º 2
0
            public void GenericC()
            {
                SCG.IComparer <dbl> h = SCG.Comparer <dbl> .Default;
                dbl s = new dbl(3.4);
                dbl t = new dbl(3.4);
                dbl u = new dbl(7.4);

                Assert.AreEqual(0, h.Compare(s, t));
                Assert.IsTrue(h.Compare(s, u) < 0);
            }
Ejemplo n.º 3
0
            public void OrdinaryC()
            {
                SCG.IComparer <string> h = SCG.Comparer <string> .Default;
                string s = "bamse";
                string t = "bamse";
                string u = "bimse";

                Assert.AreEqual(0, h.Compare(s, t));
                Assert.IsTrue(h.Compare(s, u) < 0);
            }
Ejemplo n.º 4
0
            public void IntComparerViaBuilder()
            {
                SCG.IComparer <int> h = SCG.Comparer <int> .Default;
                int s = 4;
                int t = 4;
                int u = 5;

                Assert.AreEqual(0, h.Compare(s, t));
                Assert.IsTrue(h.Compare(s, u) < 0);
                Assert.AreSame(h, SCG.Comparer <int> .Default);
            }
Ejemplo n.º 5
0
            public void GenericCViaBuilder()
            {
                SCG.IComparer <dbl> h = SCG.Comparer <dbl> .Default;
                var s = new dbl(3.4);
                var t = new dbl(3.4);
                var u = new dbl(7.4);

                Assert.AreEqual(0, h.Compare(s, t));
                Assert.IsTrue(h.Compare(s, u) < 0);
                Assert.AreSame(h, SCG.Comparer <dbl> .Default);
            }
Ejemplo n.º 6
0
            public void OrdinaryCViaBuilder()
            {
                SCG.IComparer <string> h = SCG.Comparer <string> .Default;
                var s = "bamse";
                var t = "bamse";
                var u = "bimse";

                Assert.AreEqual(0, h.Compare(s, t));
                Assert.IsTrue(h.Compare(s, u) < 0);
                Assert.AreSame(h, SCG.Comparer <string> .Default);
            }
        public void Sort_Comparison_WithoutDuplicates(int count)
        {
            List <T> list = GenericListFactory(count);

            SCG.IComparer <T> iComparer = GetIComparer();
            Comparison <T>    comparer  = ((T first, T second) => { return(iComparer.Compare(first, second)); });

            list.Sort(comparer);
            Assert.All(Enumerable.Range(0, count - 2), i =>
            {
                Assert.True(iComparer.Compare(list[i], list[i + 1]) < 0);
            });
        }
Ejemplo n.º 8
0
        public bool Add(T item)
        {
            Node[] update = new Node[maxLevel];
            Node   x      = header;

            for (int i = level; i >= 0; i--)
            {
                while (x.forward[i] != null && comparer.Compare(x.forward[i].value, item) < 0)
                {
                    x = x.forward[i];
                }
                update[i] = x;
            }
            int newLevel = RandomLevel();

            if (newLevel > level)
            {
                for (int i = level + 1; i < newLevel; i++)
                {
                    update[i] = header;
                }
                level = newLevel;
            }
            x = new Node(newLevel, item);
            for (int i = 0; i < newLevel; i++)
            {
                x.forward[i]         = update[i].forward[i];
                update[i].forward[i] = x;
            }
            size++;
            return(true);
        }
Ejemplo n.º 9
0
 public void SortedSet_Generic_GetViewBetween_SubsequentOutOfRangeCall_ThrowsArgumentOutOfRangeException(int setLength)
 {
     if (setLength >= 3)
     {
         SortedSet <T>     set      = (SortedSet <T>)GenericISetFactory(setLength);
         SCG.IComparer <T> comparer = GetIComparer() ?? Comparer <T> .Default;
         T firstElement             = set.ElementAt(0);
         T middleElement            = set.ElementAt(setLength / 2);
         T lastElement = set.ElementAt(setLength - 1);
         if ((comparer.Compare(firstElement, middleElement) < 0) && (comparer.Compare(middleElement, lastElement) < 0))
         {
             SortedSet <T> view = set.GetViewBetween(firstElement, middleElement);
             Assert.Throws <ArgumentOutOfRangeException>(() => view.GetViewBetween(middleElement, lastElement));
         }
     }
 }
        public void Sort_IComparer_WithoutDuplicates(int count)
        {
            List <T> list = GenericListFactory(count);

            SCG.IComparer <T> comparer = GetIComparer();
            list.Sort(comparer);
            Assert.All(Enumerable.Range(0, count - 2), i =>
            {
                Assert.True(comparer.Compare(list[i], list[i + 1]) < 0);
            });
        }
        public void Sort_WithDuplicates(int count)
        {
            List <T> list = GenericListFactory(count);

            list.Add(list[0]);
            SCG.IComparer <T> comparer = Comparer <T> .Default;
            list.Sort();
            Assert.All(Enumerable.Range(0, count - 2), i =>
            {
                Assert.True(comparer.Compare(list[i], list[i + 1]) <= 0);
            });
        }
Ejemplo n.º 12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="item">The item to search for</param>
        /// <param name="middle">The least index, middle, for which array[middle] >= item</param>
        /// <returns>True if item found</returns>
        private bool BinarySearch(T item, out int middle)
        {
            int bottom = 0, top = size;

            middle = top / 2;

            while (top > bottom)
            {
                int comparer;

                if ((comparer = _comparer.Compare(array[middle], item)) == 0)
                {
                    return(true);
                }

                if (comparer > 0)
                {
                    top = middle;
                }
                else
                {
                    bottom = middle + 1;
                }

                middle = bottom + ((top - bottom) / 2);
            }

            return(false);
        }
Ejemplo n.º 13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="item">The item to search for</param>
        /// <param name="mid">The least index, mid, for which array[mid] >= item</param>
        /// <returns>True if item found</returns>
        private bool binarySearch(T item, out int mid)
        {
            int bot = 0, top = Size;

            mid = top / 2;
            while (top > bot)
            {
                int c;

                if ((c = _comparer.Compare(array[mid], item)) == 0)
                {
                    return(true);
                }

                if (c > 0)
                {
                    top = mid;
                }
                else
                {
                    bot = mid + 1;
                }

                mid = (bot + top) / 2;
            }

            return(false);
        }
Ejemplo n.º 14
0
        private bool add(T item)
        {
            Node[] update = new Node[maxLevel];
            Node   node1  = header;
            Node   node2;
            Node   newNode;
            bool   lockTaken = false;

            for (int i = maxLevel - 1; i >= 0; i--)
            {
                node2 = node1.forward[i];
                while (node2.tail != true && comparer.Compare(node2.value, item) < 0)
                {
                    node1 = node2;
                    node2 = node2.forward[i];
                }
                update[i] = node1;
            }

            int newLevel = RandomLevel();

            newNode           = new Node(newLevel, item);
            newNode.timeStamp = DateTime.MaxValue.Ticks / TimeSpan.TicksPerMillisecond;
            lock (newNode.nodeLock)
            {
                for (int i = 0; i < newLevel; i++)
                {
                    try
                    {
                        node1 = getLock(update[i], item, i, ref lockTaken);

                        newNode.forward[i] = node1.forward[i];
                        node1.forward[i]   = newNode;
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            Monitor.Exit(node1.levelLock[i]);
                            lockTaken = false;
                        }
                    }
                }
            }
            newNode.timeStamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            Interlocked.Increment(ref size);
            return(true);
        }
Ejemplo n.º 15
0
 public void SortedSet_Generic_GetViewBetween_LowerValueGreaterThanUpperValue_ThrowsArgumentException(int setLength)
 {
     if (setLength >= 2)
     {
         SCG.IComparer <T> comparer = GetIComparer() ?? Comparer <T> .Default;
         SortedSet <T>     set      = (SortedSet <T>)GenericISetFactory(setLength);
         T firstElement             = set.ElementAt(0);
         T lastElement = set.ElementAt(setLength - 1);
         if (comparer.Compare(firstElement, lastElement) < 0)
         {
             AssertExtensions.Throws <ArgumentException>("lowerValue", /*null,*/ () => set.GetViewBetween(lastElement, firstElement));
         }
     }
 }
Ejemplo n.º 16
0
        public void SortedSet_Generic_GetViewBetween_MiddleOfSet(int setLength)
        {
            if (setLength >= 3)
            {
                SCG.IComparer <T> comparer = GetIComparer() ?? Comparer <T> .Default;
                SortedSet <T>     set      = (SortedSet <T>)GenericISetFactory(setLength);
                T firstElement             = set.ElementAt(1);
                T lastElement = set.ElementAt(setLength - 2);

                SCG.List <T> expected = new SCG.List <T>(setLength - 2);
                foreach (T value in set)
                {
                    if (comparer.Compare(value, firstElement) >= 0 && comparer.Compare(value, lastElement) <= 0)
                    {
                        expected.Add(value);
                    }
                }

                SortedSet <T> view = set.GetViewBetween(firstElement, lastElement);
                Assert.Equal(expected.Count, view.Count);
                Assert.True(view.SetEquals(expected));
            }
        }
Ejemplo n.º 17
0
        public static bool IsSorted <T>(this SCG.IEnumerable <T> enumerable, SCG.IComparer <T> comparer)
        {
            #region Code Contracts

            // Argument must be non-null
            Requires(enumerable != null, ArgumentMustBeNonNull);

            #endregion

            if (comparer == null)
            {
                comparer = SCG.Comparer <T> .Default;
            }

            return(enumerable.AllConsecutiveElements((x, y) => comparer.Compare(x, y) <= 0));
        }
Ejemplo n.º 18
0
 public void ComparerViaBuilderTest <T>(T item1, T item2)
     where T : IComparable <T>
 {
     SCG.IComparer <T> h = SCG.Comparer <T> .Default;
     Assert.AreSame(h, SCG.Comparer <T> .Default);
     Assert.AreEqual(0, h.Compare(item1, item1));
     Assert.AreEqual(0, h.Compare(item2, item2));
     Assert.IsTrue(h.Compare(item1, item2) < 0);
     Assert.IsTrue(h.Compare(item2, item1) > 0);
     Assert.AreEqual(Math.Sign(item1.CompareTo(item2)), Math.Sign(h.Compare(item1, item2)));
     Assert.AreEqual(Math.Sign(item2.CompareTo(item1)), Math.Sign(h.Compare(item2, item1)));
 }
        public void Sort_intintIComparer_WithoutDuplicates(int count)
        {
            List <T> unsortedList = GenericListFactory(count);

            SCG.IComparer <T> comparer = GetIComparer();
            for (int startIndex = 0; startIndex < count - 2; startIndex++)
            {
                for (int sortCount = 1; sortCount < count - startIndex; sortCount++)
                {
                    List <T> list = new List <T>(unsortedList);
                    list.Sort(startIndex, sortCount + 1, comparer);
                    for (int i = startIndex; i < sortCount; i++)
                    {
                        Assert.InRange(comparer.Compare(list[i], list[i + 1]), int.MinValue, 0);
                    }
                }
            }
        }
Ejemplo n.º 20
0
        public T FindMin()
        {
            // Collection must be non-empty
            Requires(!IsEmpty, CollectionMustBeNonEmpty);


            // Result is non-null
            Ensures(AllowsNull || Result <T>() != null);

            // All items in the collection are greater than or equal to the result
            Ensures(ForAll(this, item => Comparer.Compare(item, Result <T>()) >= 0));

            // The count remains the same
            Ensures(Count == OldValue(Count));

            // Return value is from the collection
            Ensures(this.ContainsSame(Result <T>()));


            return(default(T));
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Create a new indexed sorted collection consisting of the results of
        /// mapping all items of this list.
        /// <exception cref="ArgumentException"/> if the map is not increasing over 
        /// the items of this collection (with respect to the two given comparison 
        /// relations).
        /// </summary>
        /// <param name="m">The delegate definging the map.</param>
        /// <param name="c">The comparion relation to use for the result.</param>
        /// <returns>The new sorted collection.</returns>
        public IIndexedSorted<V> Map<V>(Func<T, V> m, SCG.IComparer<V> c)
        {
            SortedArray<V> res = new SortedArray<V>(size, c);

            if (size > 0)
            {
                V oldv = res.array[0] = m(array[0]), newv;

                for (int i = 1; i < size; i++)
                {
                    if (c.Compare(oldv, newv = res.array[i] = m(array[i])) >= 0)
                        throw new ArgumentException("mapper not monotonic");

                    oldv = newv;
                }
            }

            res.size = size;
            return res;
        }
Ejemplo n.º 22
0
        public bool Check()
        {
            if (size == 0)
            {
                return(true);
            }

            for (int i = 0; i <= maxLevel - 1; i++)
            {
                Node x = header;
                //header is 0 (and we allow for dupliates as of 21/11/2016), so we have to check if the previous node is greater then or equel to the current one
                while (!x.forward[i].tail && comparer.Compare(x.value, x.forward[i].value) <= 0)
                {
                    x = x.forward[i];
                }

                //If the the next element isen't null, there's an element next x (the supposed last and least element), and the list is out of order
                if (!x.forward[i].tail)
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Equality of two items as defined by the comparer.
 /// </summary>
 /// <param name="item1"></param>
 /// <param name="item2"></param>
 /// <returns></returns>
 public bool Equals(T item1, T item2)
 {
     return(comparer.Compare(item1, item2) == 0);
 }
Ejemplo n.º 24
0
 private static SCG.IComparer <T> ReverseComparer <T>(SCG.IComparer <T> cmp)
 {
     return(ComparerFactory <T> .CreateComparer((item1, item2) => cmp.Compare(item2, item1)));
 }
Ejemplo n.º 25
0
        public T DeleteMax()
        {
            bool globalLockAcquired = false, iIntervalLockAcquired = false,
                 lIntervalLockAcquired = false, rIntervalLockAcquired = false;
            int i = 0;

            Monitor.Enter(globalLock, ref globalLockAcquired); //acquire global lock and mark it aquired.
            try
            {
                if (size == 0)
                {
                    throw new NoSuchItemException();
                }

                T retval;
                if (size == 1)                  //if there is only one element in the heap, assign it as a return value.
                {
                    lock (heap[0].intervalLock) //lock
                    {
                        size = 0;
                        if (globalLockAcquired)
                        {
                            Monitor.Exit(globalLock); //exit global lock
                            globalLockAcquired = false;
                        }
                        retval           = heap[0].first;
                        heap[0].first    = default(T);
                        heap[0].firstTag = Empty;
                    }
                }
                else
                {
                    Interval last     = new Interval();
                    int      s        = size;
                    int      lastcell = (size - 1) / 2;
                    lock (heap[lastcell].intervalLock)
                    {
                        size--;
                        if (globalLockAcquired)
                        {
                            Monitor.Exit(globalLock); //exit global lock
                            globalLockAcquired = false;
                        }
                        if (s % 2 == 0)
                        {
                            last.last              = heap[lastcell].last;
                            heap[lastcell].last    = default(T);
                            heap[lastcell].lastTag = Empty;
                        }
                        else
                        {
                            last.last               = heap[lastcell].first;
                            heap[lastcell].first    = default(T);
                            heap[lastcell].firstTag = Empty;
                        }
                    }

                    Monitor.Enter(heap[0].intervalLock, ref iIntervalLockAcquired); //acquire lock of first interval node and mark it aquired.
                    try
                    {
                        if (heap[0].firstTag == Empty)
                        {
                            retval = last.last;
                            return(retval);
                        }
                        if (heap[0].lastTag == Empty)
                        {
                            if (comparer.Compare(last.last, heap[0].first) >= 0)
                            {
                                retval = last.last;
                                return(retval);
                            }
                            else
                            {
                                retval           = heap[0].first;
                                heap[0].first    = last.last;
                                heap[0].firstTag = Available;
                                return(retval);
                            }
                        }

                        if (comparer.Compare(last.last, heap[0].last) >= 0)
                        {
                            retval = last.last;
                            return(retval);
                        }
                        else
                        {
                            retval          = heap[0].last;
                            heap[0].last    = last.last;
                            heap[0].lastTag = Available;
                        }

                        #region Heapify max

                        i = 0; //node index at which we satrt heapify max
                        while (true)
                        {
                            if (heap[i].lastTag != Empty && comparer.Compare(heap[i].last, heap[i].first) < 0)
                            {
                                T first = heap[i].first;
                                heap[i].first = heap[i].last;
                                heap[i].last  = first;
                            }
                            int  currentMax = i;
                            int  l          = 2 * i + 1;
                            int  r          = l + 1;
                            bool firstMax   = false;

                            if (l < heap.Length)
                            {
                                Monitor.Enter(heap[l].intervalLock, ref lIntervalLockAcquired);
                            }

                            if (r < heap.Length) //try to obtain a lock on righ child if exist
                            {
                                Monitor.Enter(heap[r].intervalLock, ref rIntervalLockAcquired);
                            }
                            try
                            {
                                if (lIntervalLockAcquired && heap[l].firstTag == Empty)
                                {
                                    break;
                                }

                                if (lIntervalLockAcquired && heap[l].lastTag != Empty)             //if lock was aquired and left child has min and max element
                                {
                                    if (comparer.Compare(heap[l].last, heap[currentMax].last) > 0) //if left child's max node is greather
                                    {
                                        currentMax = l;                                            //left child becomes max node
                                    }
                                }
                                else if (lIntervalLockAcquired && heap[l].lastTag == Empty)         //if lock was aquired and left child only has min element
                                {
                                    if (comparer.Compare(heap[l].first, heap[currentMax].last) > 0) // if left child's min node is greater
                                    {
                                        currentMax = l;                                             //left child becomes max node
                                        firstMax   = true;                                          //indicate that node's min element is max.
                                    }
                                }

                                if (rIntervalLockAcquired && heap[r].lastTag != Empty)             //if lock was aquired and lright child has min and max element
                                {
                                    if (comparer.Compare(heap[r].last, heap[currentMax].last) > 0) //if right child's max node is greather
                                    {
                                        currentMax = r;                                            //right child becomes max node
                                    }
                                }
                                else if (rIntervalLockAcquired && heap[r].lastTag == Empty) //if lock was aquired and right child only has min element
                                {
                                    if (comparer.Compare(heap[r].first, heap[currentMax].last) > 0)
                                    {
                                        currentMax = r;    //right child becomes max node
                                        firstMax   = true; //indicate that node's min element is max.
                                    }
                                }

                                if (currentMax != i) // if max node is not the parent node...
                                {
                                    if (firstMax)
                                    {
                                        T first = heap[currentMax].first;
                                        heap[currentMax].last = heap[i].last;
                                        heap[i].last          = first;
                                        //swapFirstWithLast(currentMax, i);
                                    }
                                    else
                                    {
                                        swapLastWithLast(currentMax, i);
                                    }

                                    if (currentMax == l) //if left child is the node that has max value
                                    {
                                        if (rIntervalLockAcquired)
                                        {
                                            Monitor.Exit(heap[r].intervalLock); //unlock right child
                                        }
                                    }
                                    else if (currentMax == r) //if right child is the node that has max value
                                    {
                                        if (lIntervalLockAcquired)
                                        {
                                            Monitor.Exit(heap[l].intervalLock); //unlock left child
                                        }
                                    }

                                    if (iIntervalLockAcquired)
                                    {
                                        Monitor.Exit(heap[i].intervalLock); //release parent node lock, aka i'th node
                                    }
                                    i = currentMax;                         //new parent becomes either right or left child.
                                    iIntervalLockAcquired = true;           //since one of the child becomes parent, it is still locked
                                    lIntervalLockAcquired = false;          //reset lock flag
                                    rIntervalLockAcquired = false;          //reset lock flag
                                    continue;                               //continue with the while loop
                                }
                                break;                                      //exit while loop
                            }
                            finally
                            {
                                if (lIntervalLockAcquired)
                                {
                                    Monitor.Exit(heap[l].intervalLock);
                                }
                                if (rIntervalLockAcquired)
                                {
                                    Monitor.Exit(heap[r].intervalLock);
                                }
                            }
                        } //end while

                        #endregion
                    }
                    finally
                    {
                        if (iIntervalLockAcquired)
                        {
                            Monitor.Exit(heap[i].intervalLock);
                        }
                    }
                } //end else
                return(retval);
            }
            finally
            {
                if (globalLockAcquired)
                {
                    Monitor.Exit(globalLock); //exit global lock
                    globalLockAcquired = false;
                }
            }
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Compare two entries
 /// </summary>
 /// <param name="entry1">First entry</param>
 /// <param name="entry2">Second entry</param>
 /// <returns>The result of comparing the keys</returns>
 public int Compare(KeyValuePair <K, V> entry1, KeyValuePair <K, V> entry2)
 {
     return(comparer.Compare(entry1.Key, entry2.Key));
 }
Ejemplo n.º 27
0
 private int compare(T i1, T i2)
 {
     return(c.Compare(i1, i2));
 }
Ejemplo n.º 28
0
        bool heapifyMin(int i)
        {
            bool   swappedroot = false;
            int    cell = i, currentmin = cell;
            T      currentitem   = heap[cell].first;
            Handle currenthandle = heap[cell].firsthandle;

            if (i > 0)
            {
                T other = heap[cell].last;
                if (2 * cell + 1 < size && comparer.Compare(currentitem, other) > 0)
                {
                    swappedroot = true;
                    Handle otherhandle = heap[cell].lasthandle;
                    updateLast(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }
            }

            T      minitem   = currentitem;
            Handle minhandle = currenthandle;

            while (true)
            {
                int l = 2 * cell + 1, r = l + 1;
                T   lv, rv;

                if (2 * l < size && comparer.Compare(lv = heap[l].first, minitem) < 0)
                {
                    currentmin = l; minitem = lv;
                }

                if (2 * r < size && comparer.Compare(rv = heap[r].first, minitem) < 0)
                {
                    currentmin = r; minitem = rv;
                }

                if (currentmin == cell)
                {
                    break;
                }

                minhandle = heap[currentmin].firsthandle;
                updateFirst(cell, minitem, minhandle);
                cell = currentmin;

                //Maybe swap first and last
                T other = heap[cell].last;
                if (2 * currentmin + 1 < size && comparer.Compare(currentitem, other) > 0)
                {
                    Handle otherhandle = heap[cell].lasthandle;
                    updateLast(cell, currentitem, currenthandle);
                    currentitem   = other;
                    currenthandle = otherhandle;
                }


                minitem   = currentitem;
                minhandle = currenthandle;
            }

            if (cell != i || swappedroot)
            {
                updateFirst(cell, minitem, minhandle);
            }
            return(swappedroot);
        }
Ejemplo n.º 29
0
 public static SCG.IComparer <T> ReverseComparer <T>(SCG.IComparer <T> cmp)
 {
     return(new DelegateComparer <T>(
                delegate(T item1, T item2) { return cmp.Compare(item2, item1); }));
 }
Ejemplo n.º 30
0
        private bool HeapifyMin(int cell)
        {
            bool swappedroot = false;

            // If first > last, swap them
            if (2 * cell + 1 < size && comparer.Compare(heap[cell].first, heap[cell].last) > 0)
            {
                swappedroot = true;
                SwapFirstWithLast(cell, cell);
            }

            int currentmin = cell, l = 2 * cell + 1, r = l + 1;

            if (2 * l < size && comparer.Compare(heap[l].first, heap[currentmin].first) < 0)
            {
                currentmin = l;
            }

            if (2 * r < size && comparer.Compare(heap[r].first, heap[currentmin].first) < 0)
            {
                currentmin = r;
            }

            if (currentmin != cell)
            {
                // cell has at least one daughter, and it contains the min
                SwapFirstWithFirst(currentmin, cell);
                HeapifyMin(currentmin);
            }
            return(swappedroot);
        }