C#,数值计算——多种经典排序算法(sort)的计算方法与源程序

using System;

namespace Legalsoft.Truffer
{
    public class Sorter
    {
        public Sorter() { }

        public static void sort(double[] arr)
        {
            sort(arr, -1);
        }

        public static void sort(double[] arr, int m = -1)
        {
            const int M = 7;
            const int NSTACK = 64;
            int jstack = -1;
            int l = 0;
            int n = arr.Length;
            double a;
            int[] istack = new int[NSTACK];
            if (m > 0)
            {
                n = Math.Min(m, n);
            }
            int ir = n - 1;
            for (; ; )
            {
                if (ir - l < M)
                {
                    for (int j = l + 1; j <= ir; j++)
                    {
                        a = arr[j];
                        int i = j - 1;
                        for (; i >= l; i--)
                        {
                            //if (arr[i].CompareTo(a) <= 0)
                            if (arr[i] <= a)
                            {
                                break;
                            }
                            arr[i + 1] = arr[i];
                        }
                        arr[i + 1] = a;
                    }
                    if (jstack < 0)
                    {
                        break;
                    }
                    ir = istack[jstack--];
                    l = istack[jstack--];
                }
                else
                {
                    int k = (l + ir) >> 1;
                    Globals.SWAP(ref arr[k], ref arr[l + 1]);

                    if (arr[l] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l], ref arr[ir]);
                    }
                    if (arr[l + 1] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l + 1], ref arr[ir]);
                    }
                    if (arr[l] > arr[l + 1])
                    {
                        Globals.SWAP(ref arr[l], ref arr[l + 1]);
                    }
                    int i = l + 1;
                    int j = ir;
                    a = arr[l + 1];
                    for (; ; )
                    {
                        do
                        {
                            i++;
                        } while (arr[i] < a);
                        do
                        {
                            j--;
                        } while (arr[j] > a);
                        if (j < i)
                        {
                            break;
                        }
                        Globals.SWAP(ref arr[i], ref arr[j]);
                    }
                    arr[l + 1] = arr[j];
                    arr[j] = a;
                    jstack += 2;
                    if (jstack >= NSTACK)
                    {
                        throw new Exception("NSTACK too small in sort.");
                    }
                    if (ir - i + 1 >= j - l)
                    {
                        istack[jstack] = ir;
                        istack[jstack - 1] = i;
                        ir = j - 1;
                    }
                    else
                    {
                        istack[jstack] = j - 1;
                        istack[jstack - 1] = l;
                        l = i;
                    }
                }
            }
        }

        public static void hpsort(double[] ra)
        {
            int n = ra.Length;
            for (int i = n / 2 - 1; i >= 0; i--)
            {
                sift_down(ra, i, n - 1);
            }
            for (int i = n - 1; i > 0; i--)
            {
                Globals.SWAP(ref ra[0], ref ra[i]);
                sift_down(ra, 0, i - 1);
            }
        }

        public static void sift_down(double[] ra, int l, int r)
        {
            double a = ra[l];
            int jold = l;
            int j = 2 * l + 1;
            while (j <= r)
            {
                if (j < r && ra[j] < ra[j + 1])
                {
                    j++;
                }
                if (a >= ra[j])
                {
                    break;
                }
                ra[jold] = ra[j];
                jold = j;
                j = 2 * j + 1;
            }
            ra[jold] = a;
        }

        public static void piksrt(double[] arr)
        {
            int n = arr.Length;
            for (int j = 1; j < n; j++)
            {
                double a = arr[j];
                int i = j;
                while (i > 0 && arr[i - 1] > a)
                {
                    arr[i] = arr[i - 1];
                    i--;
                }
                arr[i] = a;
            }
        }

        public static void piksr2(double[] arr, double[] brr)
        {
            int n = arr.Length;
            for (int j = 1; j < n; j++)
            {
                double a = arr[j];
                double b = brr[j];
                int i = j;
                while (i > 0 && arr[i - 1] > a)
                {
                    arr[i] = arr[i - 1];
                    brr[i] = brr[i - 1];
                    i--;
                }
                arr[i] = a;
                brr[i] = b;
            }
        }

        public static double select(int k, double[] arr)
        {
            int n = arr.Length;
            double a;
            int l = 0;
            int ir = n - 1;
            for (; ; )
            {
                if (ir <= l + 1)
                {
                    if (ir == l + 1 && arr[ir] < arr[l])
                    {
                        Globals.SWAP(ref arr[l], ref arr[ir]);
                    }
                    return arr[k];
                }
                else
                {
                    int mid = (l + ir) >> 1;
                    Globals.SWAP(ref arr[mid], ref arr[l + 1]);
                    if (arr[l] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l], ref arr[ir]);
                    }
                    if (arr[l + 1] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l + 1], ref arr[ir]);
                    }
                    if (arr[l] > arr[l + 1])
                    {
                        Globals.SWAP(ref arr[l], ref arr[l + 1]);
                    }
                    int i = l + 1;
                    int j = ir;
                    a = arr[l + 1];
                    for (; ; )
                    {
                        do
                        {
                            i++;
                        } while (arr[i] < a);
                        do
                        {
                            j--;
                        } while (arr[j] > a);
                        if (j < i)
                        {
                            break;
                        }
                        Globals.SWAP(ref arr[i], ref arr[j]);
                    }
                    arr[l + 1] = arr[j];
                    arr[j] = a;
                    if (j >= k)
                    {
                        ir = j - 1;
                    }
                    if (j <= k)
                    {
                        l = i;
                    }
                }
            }
        }

        public static void shell(double[] a, int m = -1)
        {
            int n = a.Length;
            if (m > 0)
            {
                n = Math.Min(m, n);
            }
            int inc = 1;
            do
            {
                inc *= 3;
                inc++;
            } while (inc <= n);
            do
            {
                inc /= 3;
                for (int i = inc; i < n; i++)
                {
                    double v = a[i];
                    int j = i;
                    //if (a[j - inc].CompareTo(v) > 0)
                    while (a[j - inc] > v)
                    {
                        a[j] = a[j - inc];
                        j -= inc;
                        if (j < inc)
                        {
                            break;
                        }
                    }
                    a[j] = v;
                }
            } while (inc > 1);
        }

        public static void sort2(double[] arr, double[] brr)
        {
            const int M = 7;
            const int NSTACK = 64;
            int jstack = -1;
            int l = 0;
            int n = arr.Length;
            int[] istack = new int[NSTACK];
            int ir = n - 1;
            for (; ; )
            {
                if (ir - l < M)
                {
                    for (int j = l + 1; j <= ir; j++)
                    {
                        double a = arr[j];
                        double b = brr[j];
                        int i = j - 1;
                        for (; i >= l; i--)
                        {
                            if (arr[i] <= a)
                            {
                                break;
                            }
                            arr[i + 1] = arr[i];
                            brr[i + 1] = brr[i];
                        }
                        arr[i + 1] = a;
                        brr[i + 1] = b;
                    }
                    if (jstack < 0)
                    {
                        break;
                    }
                    ir = istack[jstack--];
                    l = istack[jstack--];
                }
                else
                {
                    int k = (l + ir) >> 1;
                    Globals.SWAP(ref arr[k], ref arr[l + 1]);
                    Globals.SWAP(ref brr[k], ref brr[l + 1]);

                    if (arr[l] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l], ref arr[ir]);
                        Globals.SWAP(ref brr[l], ref brr[ir]);
                    }
                    if (arr[l + 1] > arr[ir])
                    {
                        Globals.SWAP(ref arr[l + 1], ref arr[ir]);
                        Globals.SWAP(ref brr[l + 1], ref brr[ir]);
                    }
                    if (arr[l] > arr[l + 1])
                    {
                        Globals.SWAP(ref arr[l], ref arr[l + 1]);
                        Globals.SWAP(ref brr[l], ref brr[l + 1]);
                    }
                    int i = l + 1;
                    int j = ir;
                    double a = arr[l + 1];
                    double b = brr[l + 1];
                    for (; ; )
                    {
                        do
                        {
                            i++;
                        } while (arr[i] < a);
                        do
                        {
                            j--;
                        } while (arr[j] > a);
                        if (j < i)
                        {
                            break;
                        }
                        Globals.SWAP(ref arr[i], ref arr[j]);
                        Globals.SWAP(ref brr[i], ref brr[j]);
                    }
                    arr[l + 1] = arr[j];
                    arr[j] = a;
                    brr[l + 1] = brr[j];
                    brr[j] = b;
                    jstack += 2;
                    if (jstack >= NSTACK)
                    {
                        throw new Exception("NSTACK too small in sort2.");
                    }
                    if (ir - i + 1 >= j - l)
                    {
                        istack[jstack] = ir;
                        istack[jstack - 1] = i;
                        ir = j - 1;
                    }
                    else
                    {
                        istack[jstack] = j - 1;
                        istack[jstack - 1] = l;
                        l = i;
                    }
                }
            }
        }

        /// <summary>
        /// select Mth largest in place
        /// </summary>
        /// <param name="k"></param>
        /// <param name="arr"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static double selip(int k, double[] arr)
        {
            const int M = 64;
            const double BIG = 9.99e99;
            int n = arr.Length;
            int[] isel = new int[M + 2];
            double[] sel = new double[M + 2];

            if (k < 0 || k > n - 1)
            {
                throw new Exception("bad input to selip");
            }
            int kk = k;
            double ahi = BIG;
            double alo = -BIG;
            for (; ; )
            {
                int mm = 0;
                int nlo = 0;
                double sum = 0.0;
                int nxtmm = M + 1;
                for (int i = 0; i < n; i++)
                {
                    if (arr[i] >= alo && arr[i] <= ahi)
                    {
                        mm++;
                        //if (arr[i] == alo)
                        if (Math.Abs(arr[i] - alo) <= float.Epsilon)
                        {
                            nlo++;
                        }
                        if (mm <= M)
                        {
                            sel[mm - 1] = arr[i];
                        }
                        else if (mm == nxtmm)
                        {
                            nxtmm = mm + mm / M;
                            sel[(i + 2 + mm + kk) % M] = arr[i];
                        }
                        sum += arr[i];
                    }
                }
                if (kk < nlo)
                {
                    return alo;
                }
                else if (mm < M + 1)
                {
                    shell(sel, mm);
                    ahi = sel[kk];
                    return ahi;
                }
                sel[M] = sum / mm;
                shell(sel, M + 1);
                sel[M + 1] = ahi;

                int j = 0;
                for (; j < M + 2; j++)
                {
                    isel[j] = 0;
                }

                for (int i = 0; i < n; i++)
                {
                    if (arr[i] >= alo && arr[i] <= ahi)
                    {
                        int jl = 0;
                        int ju = M + 2;
                        while (ju - jl > 1)
                        {
                            int jm = (ju + jl) / 2;
                            if (arr[i] >= sel[jm - 1])
                            {
                                jl = jm;
                            }
                            else
                            {
                                ju = jm;
                            }
                        }
                        isel[ju - 1]++;
                    }
                }

                j = 0;
                while (kk >= isel[j])
                {
                    alo = sel[j];
                    kk -= isel[j++];
                }
                ahi = sel[j];
            }
        }

    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/132051718
今日推荐