예제 #1
0
        /// <summary>
        /// Provides a static method for sorting an array using an optimized binary insertion sort with half exchanges.
        /// The sorting algorithm is stable and uses O(1) extra memory.
        ///
        ///  This implementation makes ~ n lg n compares for any array of length n.
        ///  However, in the worst case, the running time is quadratic because the number of array accesses can be proportional to n^2 (e.g, if the array is reverse sorted).
        ///  As such, it is not suitable for sorting large arrays(unless the number of inversions is small).
        /// </summary>
        /// <param name="a">array to sort</param>
        public static void Sort(T[] a)
        {
            int n = a.Length;

            for (int i = 1; i < n; i++)
            {
                // binary search to determine index j at which to insert a[i]
                var v = a[i];
                int lo = 0, hi = i;
                while (lo < hi)
                {
                    int mid = lo + (hi - lo) / 2;
                    if (SortingHelper <T> .less(v, a[mid]))
                    {
                        hi = mid;
                    }
                    else
                    {
                        lo = mid + 1;
                    }
                }

                // insetion sort with "half exchanges"
                // (insert a[i] at index j and shift a[j], ..., a[i-1] to right)
                for (int j = i; j > lo; --j)
                {
                    a[j] = a[j - 1];
                }
                a[lo] = v;
            }

            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #2
0
        /// <summary>
        /// quicksort the subarray a[lo .. hi] using 3-way partitioning
        /// </summary>
        /// <param name="a"></param>
        /// <param name="lo"></param>
        /// <param name="hi"></param>
        private static void sort(T[] a, int lo, int hi)
        {
            if (hi <= lo)
            {
                return;
            }
            int lt = lo, gt = hi;
            T   v = a[lo];
            int i = lo;

            while (i <= gt)
            {
                int cmp = a[i].CompareTo(v);
                if (cmp < 0)
                {
                    SortingHelper <T> .exch(a, lt ++, i ++);
                }
                else if (cmp > 0)
                {
                    SortingHelper <T> .exch(a, i, gt --);
                }
                else
                {
                    i++;
                }
            }

            // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
            sort(a, lo, lt - 1);
            sort(a, gt + 1, hi);
            Debug.Assert(SortingHelper <T> .isSorted(a, lo, hi));
        }
예제 #3
0
        /// <summary>
        /// Rearranges the array in ascending order, using the natural order.
        /// </summary>
        /// <param name="a">the array to be sorted</param>
        public static void Sort(T[] a)
        {
            StdRandom.shuffle(a);

            sort(a, 0, a.Length - 1);
            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #4
0
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void Sort(T[] a)
        {
            var aux = new T[a.Length];

            sort(a, aux, 0, a.Length - 1);
            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #5
0
        private const int CUTOFF = 7;  // cutoff to insertion sort

        // This class should not be instantiated.
        private static void merge(T[] src, T[] dst, int lo, int mid, int hi)
        {
            // precondition: src[lo .. mid] and src[mid+1 .. hi] are sorted subarrays
            Debug.Assert(SortingHelper <T> .isSorted(src, lo, mid));
            Debug.Assert(SortingHelper <T> .isSorted(src, mid + 1, hi));

            int i = lo, j = mid + 1;

            for (int k = lo; k <= hi; k++)
            {
                if (i > mid)
                {
                    dst[k] = src[j++];
                }
                else if (j > hi)
                {
                    dst[k] = src[i++];
                }
                else if (SortingHelper <T> .less(src[j], src[i]))
                {
                    dst[k] = src[j++];                                               // to ensure stability
                }
                else
                {
                    dst[k] = src[i++];
                }
            }

            // postcondition: dst[lo .. hi] is sorted subarray
            Debug.Assert(SortingHelper <T> .isSorted(dst, lo, hi));
        }
예제 #6
0
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void Sort(T[] a)
        {
            int n = a.Length;

            // 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, ...
            int h = 1;

            while (h < n / 3)
            {
                h = 3 * h + 1;
            }

            while (h >= 1)
            {
                // h-sort the array
                for (int i = h; i < n; i++)
                {
                    for (int j = i; j >= h && SortingHelper <T> .less(a[j], a[j - h]); j -= h)
                    {
                        SortingHelper <T> .exch(a, j, j - h);
                    }
                }
                Debug.Assert(isHSorted(a, h));
                h /= 3;
            }
            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #7
0
 /// <summary>
 /// Rearranges the subarray a[lo..hi) in ascending order, using a comparator.
 /// </summary>
 /// <param name="a">the array</param>
 /// <param name="lo">left endpoint (inclusive)</param>
 /// <param name="hi">right endpoint (exclusive)</param>
 /// <param name="comparator">the comparator specifying the order</param>
 public static void Sort(T[] a, int lo, int hi, IComparer <T> comparator)
 {
     for (int i = lo; i < hi; i++)
     {
         for (int j = i; j > lo && SortingHelper <T> .less(a[j], a[j - 1], comparator); j--)
         {
             SortingHelper <T> .exch(a, j, j - 1);
         }
     }
     Debug.Assert(SortingHelper <T> .isSorted(a, lo, hi, comparator));
 }
예제 #8
0
        // quicksort the subarray from a[lo] to a[hi]
        private static void sort(T[] a, int lo, int hi)
        {
            if (hi <= lo)
            {
                return;
            }
            int j = partition(a, lo, hi);

            sort(a, lo, j - 1);
            sort(a, j + 1, hi);
            Debug.Assert(SortingHelper <T> .isSorted(a, lo, hi));
        }
예제 #9
0
        /// <summary>
        /// Rearranges the array in ascending order, using a comparator.
        /// </summary>
        /// <param name="a">the array</param>
        /// <param name="comparator">the comparator specifying the order</param>
        public static void Sort(T[] a, IComparer <T> comparator)
        {
            int n = a.Length;

            for (int i = 0; i < n; i++)
            {
                for (int j = i; j > 0 && SortingHelper <T> .less(a[j], a[j - 1], comparator); j--)
                {
                    SortingHelper <T> .exch(a, j, j - 1);
                }
                Debug.Assert(SortingHelper <T> .isSorted(a, 0, i, comparator));
            }
            Debug.Assert(SortingHelper <T> .isSorted(a, comparator));
        }
예제 #10
0
        /// <summary>
        /// Rearranges the array in ascending order, using the natural order.
        /// </summary>
        /// <param name="a">the array to be sorted</param>
        public static void Sort(T[] a)
        {
            int n   = a.Length;
            var aux = new T[n];

            for (int len = 1; len < n; len *= 2)
            {
                for (int lo = 0; lo < n - len; lo += len + len)
                {
                    int mid = lo + len - 1;
                    int hi  = Math.Min(lo + len + len - 1, n - 1);
                    merge(a, aux, lo, mid, hi);
                }
            }

            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void Sort(T[] a)
        {
            int n = a.Length;

            for (int i = 0; i < n; i++)
            {
                int min = i;
                for (int j = i + 1; j < n; j++)
                {
                    if (SortingHelper <T> .less(a[j], a[min]))
                    {
                        min = j;
                    }
                }
                SortingHelper <T> .exch(a, i, min);

                Debug.Assert(SortingHelper <T> .isSorted(a, 0, i));
            }
            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #12
0
        // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
        private static void merge(T[] a, T[] aux, int lo, int mid, int hi)
        {
            // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
            Debug.Assert(SortingHelper <T> .isSorted(a, lo, mid));
            Debug.Assert(SortingHelper <T> .isSorted(a, mid + 1, hi));

            // copy to aux[]
            for (int k = lo; k <= hi; k++)
            {
                aux[k] = a[k];
            }

            // merge back to a[]
            int i = lo, j = mid + 1;

            for (int k = lo; k <= hi; k++)
            {
                if (i > mid)
                {
                    a[k] = aux[j++];
                }
                else if (j > hi)
                {
                    a[k] = aux[i++];
                }
                else if (SortingHelper <T> .less(aux[j], aux[i]))
                {
                    a[k] = aux[j++];
                }
                else
                {
                    a[k] = aux[i++];
                }
            }

            // postcondition: a[lo .. hi] is sorted
            Debug.Assert(SortingHelper <T> .isSorted(a, lo, hi));
        }
예제 #13
0
        /// <summary>
        /// Rearranges the array in ascending order, using the natural order.
        /// </summary>
        /// <param name="a">the array to be sorted</param>
        public static void Sort(T[] a)
        {
            int n = a.Length;

            // put smallest element in position to serve as sentinel
            int exchanges = 0;

            for (int i = n - 1; i > 0; i--)
            {
                if (SortingHelper <T> .less(a[i], a[i - 1]))
                {
                    SortingHelper <T> .exch(a, i, i - 1);

                    exchanges++;
                }
            }
            if (exchanges == 0)
            {
                return;
            }


            // insertion sort with half-exchanges
            for (int i = 2; i < n; i++)
            {
                var v = a[i];
                int j = i;
                while (SortingHelper <T> .less(v, a[j - 1]))
                {
                    a[j] = a[j - 1];
                    j--;
                }
                a[j] = v;
            }

            Debug.Assert(SortingHelper <T> .isSorted(a));
        }
예제 #14
0
 /// <summary>
 /// Rearranges the array in ascending order, using the natural order.
 /// </summary>
 /// <param name="a">the array to be sorted</param>
 public static void Sort(T[] a)
 {
     T[] aux = (T[])a.Clone();
     sort(aux, a, 0, a.Length - 1);
     Debug.Assert(SortingHelper <T> .isSorted(a));
 }
 /// <summary>
 /// Searches <paramref name="i"/> within <paramref name="iarr"/> integer array.
 /// </summary>
 /// <param name="i">value</param>
 /// <param name="iarr">array</param>
 /// <returns>array index if element found, otherwise -1.</returns>
 public static int Rank(int i, int[] iarr)
 {
     Debug.Assert(SortingHelper <int> .isSorted(iarr));
     return(IndexOf(iarr, i));
 }