C# 数据结构中 排序算法

//http://www.hiahia.org/datastructure/paixu/paixu8.4.1-1.htm 参考地址

//按平均时间将排序分为四类:

//(1)平方阶(O(n2))排序
//     一般称为简单排序,例如直接插入、直接选择和冒泡排序;

//(2)线性对数阶(O(nlgn))排序
//     如快速、堆和归并排序;

//(3)O(n1+£)阶排序
//     £是介于0和1之间的常数,即0<£<1,如希尔排序;

//(4)线性阶(O(n))排序
//     如桶、箱和基数排序。

namespace ConsoleApplication1
{
    public class SortOne
    {
        public static void Main()
        {
            int[] t = { 12, 1, 3, 4, 7 };
            //t = InsertSort(t);
            //t = BInsertSort(t);
            //t = BubbleSort1(t);
            //t = BubbleSort2(t);
            //t = QuickSort(t, 0, t.Length - 1);

            //int[] temp = new int[t.Length];
            //t = MergeSort(t, temp, 0, t.Length - 1);
            //t = MergeSort1(t, 0, t.Length - 1);
            t = DirectSort(t);
            for (int i = 0; i < t.Length; i++)
                Console.Write(t[i].ToString() + " ");
            Console.Read();
        }
        #region 插入排序
        //直接插入排序 时间复杂度  O(n^2) 使用附加控件 1 
        //思路:不停的插入,比较之前的数据
        public static int[] InsertSort(int[] T)
        {
            if (T.Length <= 1) return T;
            int temp;
            for (int i = 1; i < T.Length; i++)
            {
                if (T[i] < T[i - 1])
                {
                    temp = T[i];
                    int j;
                    for (j = i - 1; j >= 0 && temp < T[j]; j--)
                    {
                        T[j + 1] = T[j];
                    }
                    T[j + 1] = temp;
                }
            }
            return T;
        }
        //直接插入排序 时间复杂度  O(n^2) 使用附加控件 1 
        //思路:不停的插入比较之前的数据;插入地址用折半查找法定位
        public static int[] BInsertSort(int[] T)
        {
            if (T.Length <= 1) return T;
            int temp;
            for (int i = 1; i < T.Length; i++)
            {
                if (T[i] < T[i - 1])
                {
                    temp = T[i];
                    int low = 0, high = i - 1, m = i - 1; //look for the move-index
                    while (low <= high)
                    {
                        m = (low + high) / 2;
                        if (T[m] > T[i]) high = m - 1;
                        else low = m + 1;
                    }
                    for (int j = i - 1; j >= m && j < T.Length - 1; j--)
                    {
                        T[j + 1] = T[j];
                    }
                    T[m] = temp;
                }
            }
            return T;
        }
        #endregion

        #region  冒泡排序
        //冒泡排序   时间复杂度   O(n^2)  不使用新的空间
        //思路: 逐次比较,轻的冒泡上浮
        public static int[] BubbleSort1(int[] T)
        {
            int Count = T.Length;
            for (int i = 0; i < Count - 1; i++)
            {
                bool exchange = false;
                for (int j = i + 1; j < Count; j++)
                {
                    if (T[i] > T[j])
                    {
                        T[i] ^= T[j];
                        T[j] ^= T[i];
                        T[i] ^= T[j];
                        exchange = true;
                    }
                }
                if (!exchange) return T;
            }
            return T;
        }

        public static int[] BubbleSort2(int[] T)
        {
            int Count = T.Length;
            bool exchange = true;
            while (Count >= 0 && exchange)
            {
                exchange = false;
                for (int i = 0; i < Count - 1; i++)
                {
                    if (T[i] > T[i + 1])
                    {
                        T[i] ^= T[i + 1];
                        T[i + 1] ^= T[i];
                        T[i] ^= T[i + 1];
                        exchange = true;
                    }
                }
                Count--;
            }
            return T;
        }
        #endregion

        #region  希尔排序  缩小增量排序,也属于插入排序的方法 ,时间效益上有较大的改进
        //先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录'基本有序',再对全体记录进行一次直接插入排序
        private static void ShellInsert(int[] T, int dk)
        {
            int temp;
            //对顺序表L做一趟希尔插入排序,前后记录的位置增量为dk,而不是之前默认的1;相隔dk的比较
            for (int i = dk; i < T.Length; i++)
            {
                if (T[i] > T[i - dk])
                {
                    int j;
                    temp = T[i];
                    for (j = i - dk; j >= 0 && T[j] > T[i]; j -= dk)
                    {
                        T[j + dk] = T[j];
                    }
                    T[j + dk] = temp;
                }
            }
        }
        public static int[] ShellSort(int[] T, int[] dks)
        {//按照dk中的数据进行比较
            for (int k = 0; k < dks.Length; k++)
                ShellInsert(T, dks[k]);//demo:dks 的数据 为: 5,3,1;其中的数据需要猜测计算,最后一个一定为1
            return T;
        }
        #endregion

        #region  快速排序   对冒泡排序的改进
        // 通过一趟排序将待排记录分割成独立的2部分,其中一部分记录的关键字比另一部分的关键字小,则可分别对这2部分继续进行排序,已达到整个序列有序
        //一般默认将T[0]做为 开始的区间轴  pivot;小的关键字放在他之前,反之放在之后,之后定位pivot
        //递归 以pivot为界限的 余下的2个区间
        private static int QuickSortPartition(int[] T, int low, int high) //一次排序,可以将 pivot放在正确的位置,左右子相对有序,左子一定小于右子
        {
            int temp;
            if (low < T.Length)
                temp = T[low];
            else return low - 1; //low index out of range
            while (low < high)
            {
                while (low < high && T[high] > temp)
                    --high;
                T[low] = T[high];
                while (low < high && T[low] < temp)
                    ++low;
                T[high] = T[low];

            }
            T[low] = temp;
            return low;
        }
        public static int[] QuickSort(int[] T, int low, int high) //递归调用
        {
            if (low < high)
            {
                int pLoc = QuickSortPartition(T, low, high);
                QuickSort(T, 0, pLoc - 1);//left
                QuickSort(T, pLoc + 1, high);//right
            }
            return T;
        }
        #endregion

        #region  选择排序
        //每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕。
        //n(n-1)/2=0(n2)
        //直接选择排序
        public static int[] DirectSort(int[] T)
        {
            if (T.Length <= 1)
                return T;
            for (int i = 0; i < T.Length; i++)
            {
                int temp = T[i];
                int min=i;
                for ( int k = i; k < T.Length; k++)
                {
                    if (temp >= T[k])
                    {
                        temp = T[k];
                        min = k;
                    }//get the least data in k...n
                }
                T[min] = T[i];
                T[i] = temp;
            }
            return T;
        }
        #endregion

        #region  归并排序
        //设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],
        //先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。
        private static void Merge(int[] T, int[] Temp, int low, int m, int high)
        {
            int start = low;
            int i = low, j = m + 1;
            while (i <= m && j <= high)
            {
                Temp[start++] = T[i] < T[j] ? T[i++] : T[j++];
            }
            while (i <= m)
            {
                Temp[start++] = T[i++];
            }
            while (j <= high)
            {
                Temp[start++] = T[j++];
            }
            while (low <= high)// 合并回去到 数组 T
            {
                T[low] = Temp[low];
                low++;
            }
        }
        public static int[] MergeSort(int[] T, int[] Temp, int low, int high)
        {
            if (low < high)
            {
                int m = (low + high) / 2;
                MergeSort(T, Temp, low, m);
                MergeSort(T, Temp, m + 1, high);
                Merge(T, Temp, low, m, high);
            }
            return T;
        }
        //dynamic malloc array length
        private static void Merge1(int[] T, int low, int m, int high)//内部分配 临时数组大小
        {
            int start = low;
            int i = low, j = m + 1; int p = 0;
            int[] Temp = new int[high - low + 1];
            while (i <= m && j <= high)
            {
                Temp[p++] = T[i] < T[j] ? T[i++] : T[j++];
            }
            while (i <= m)
            {
                Temp[p++] = T[i++];
            }
            while (j <= high)
            {
                Temp[p++] = T[j++];
            }
            for (int index = 0; low <= high; index++)// 合并回去到 数组 T
            {
                T[low] = Temp[index];
                low++;
            }
            Temp = null;
        }

        public static int[] MergeSort1(int[] T, int low, int high)
        {
            if (low < high)
            {
                int m = (low + high) / 2;
                MergeSort1(T, low, m);
                MergeSort1(T, m + 1, high);
                Merge1(T, low, m, high);
            }
            return T;
        }
        #endregion
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值