示例#1
0
        public static void RandomShuffle <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <int, int> gen
            )
        {
            var n = Distance(first, last);

            for (var i = n - 1; i > 0; --i)
            {
                first.GetAdvanced(i).Swap(first.GetAdvanced(gen(i + 1)));
            }
        }
示例#2
0
        public static ArrayIterator <T> SearchN <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            int count,
            T val,
            Func <T, T, bool> pred
            )
        {
            var limit = first.GetAdvanced(first.Distance(last) - count);

            while (first.NotEqual(limit))
            {
                var it = first;
                var i  = 0;
                while (pred(val, it.GetCurrent()))
                {
                    it = it.GetNext();
                    if (++i == count)
                    {
                        return(first);
                    }
                }
                first = first.GetNext();
            }
            return(last);
        }
示例#3
0
        public static ArrayIterator <T> IsHeapUntil <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            var len = first.Distance(last);
            var p   = 0;
            var c   = 1;
            var pp  = first;

            while (c < len)
            {
                var cp = first.GetAdvanced(c);
                if (comp(pp.GetCurrent(), cp.GetCurrent()))
                {
                    return(cp);
                }
                c++;
                cp = cp.GetNext();
                if (c == len)
                {
                    return(last);
                }
                if (comp(pp.GetCurrent(), cp.GetCurrent()))
                {
                    return(cp);
                }
                p++;
                pp = pp.GetNext();
                c  = 2 * p + 1;
            }
            return(last);
        }
示例#4
0
        public static void PushHeap <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            if (first.Distance(last) < 2)
            {
                return;
            }
            last = last.GetPrev();
            var temp   = last.GetCurrent();
            var parent = first.GetAdvanced((first.Distance(last) - 1) / 2);

            while (first.Distance(last) > 0 && comp(parent.GetCurrent(), temp))
            {
                last.SetCurrent(parent.GetCurrent());
                last   = parent;
                parent = first.GetAdvanced((first.Distance(last) - 1) / 2);
            }
            last.SetCurrent(temp);
        }
示例#5
0
        public static void InplaceMerge <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> middle,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            if (first.Index >= middle.Index || middle.Index >= last.Index)
            {
                return;
            }
            if (last.Index - first.Index == 2)
            {
                if (comp(middle.GetCurrent(), first.GetCurrent()))
                {
                    Swap(first, middle);
                }
                return;
            }
            ArrayIterator <T> firstCut;
            ArrayIterator <T> secondCut;

            if (middle.Index - first.Index > last.Index - middle.Index)
            {
                firstCut  = first.GetAdvanced(first.Distance(middle) / 2);
                secondCut = middle.LowerBound(last, firstCut.GetCurrent(), comp);
            }
            else
            {
                secondCut = middle.GetAdvanced(middle.Distance(last) / 2);
                firstCut  = first.UpperBound(middle, secondCut.GetCurrent(), comp);
            }
            Rotate(firstCut, middle, secondCut);
            middle = firstCut.GetAdvanced(middle.Distance(secondCut));
            InplaceMerge(first, firstCut, middle, comp);
            InplaceMerge(middle, secondCut, last, comp);
        }