排序算法汇总-代码

1、冒泡排序

 //冒泡排序 O(n²)
    class BubbleSort
    {
        public static void Sort(int[] arr)
        {
            int n = arr.Length;

            //外层循环控制冒泡次数
            for (int i = 0; i < n; i++)
            {
                //减去i 不需要对已经排好序的元素再次进行比较
                //内层循环在数组[0...n-1-i]范围内冒泡最大值
                //j取值范围[0...n-1-i)  j+1取值范围[1...n-1-i]
                for (int j = 0; j < n - 1 - i; j++)
                {
                    if (arr[j] > arr[j + 1])
                        Swap(arr, j, j + 1);
                }
            }
        }

        //交换数组中索引i和j对应元素的位置
        private static void Swap(int[] arr,int i,int j)
        {
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }

2、冒泡排序-泛型

class BubbleSortGeneric
    {
        public static void Sort<E>(E[] arr) where E:IComparable<E>
        {
            int n = arr.Length;

            //外层循环控制冒泡次数
            for (int i = 0; i < n; i++)
            {
                //减去i 不需要对已经排好序的元素再次进行比较
                for (int j = 0; j < n - 1 - i; j++)
                {
                    if (arr[j].CompareTo(arr[j + 1])>0)
                        Swap(arr, j, j + 1);
                }
            }
        }

        private static void Swap<E>(E[] arr, int i, int j)
        {
            E t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }

3、选择排序

 class SelectSort
    {
        public static void Sort(int[] arr)
        {
            int n = arr.Length;

            //外层循环控制每一轮循环中要交换的位置i
            //第一轮循环 i=0 执行循环体内逻辑 找到最小值然后和arr[i]交换 将第一个元素排好序
            //第二轮循环 i=1 执行循环体内逻辑 找到最小值然后和arr[i]交换 将第二个元素排好序
            //....
            //第n轮循环 i=n-1 执行循环体内逻辑 找到最小值然后和arr[i]交换 将最后一个元素排好序
            //跳出外层循环 完成整个数组的选择排序
            for (int i = 0; i < n; i++)
            {
                //最小元素的索引min 从未排序的第一个位置i开始寻找
                int min = i; 

                //内层循环在[i+1...n)寻找最小值对应的索引min
                for (int j = i+1; j < n; j++)
                {
                    if (arr[j] < arr[min])
                        min = j;
                }

                //内层循环结束,找到最小值arr[min],和未排序的边界元素arr[i]交换位置
                Swap(arr, i, min);
            }
        }

        private static void Swap(int[] arr,int i,int j)
        {
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }

4、插入排序

 class InsertSort
    {
        public int [] InSort(int [] arr)
        {
            int n = arr.Length;
            for (int i = 1; i < n; i++)
            {
                int e = arr[i];
                int j;//位置
                for ( j = i; j >0; j--)
                {
                    if (e < arr[j - 1])
                    {
                        arr[j] = arr[j - 1];
                    }
                    else
                        break;
                }
                arr[j] = e;

            }
            return arr;
        }
         //对arr[l...r]的范围使用插入排序
        public static void Sort1(int[] arr,int l,int r)
        {
            for (int i = l+1; i <= r; i++)
            {
                int e = arr[i];
                int j;
                for (j = i; j > l; j--)
                {
                    if (e < arr[j - 1])
                        arr[j] = arr[j - 1];
                    else
                        break;
                }
                arr[j] = e;
            }
        }
    }

       

5、归并排序

//时间复杂度O(nlogn)
    //空间复杂度O(n)需要借助一个同样长度的辅助数组进行排序
    class MergeSort1
    {
        //用户调用的排序方法传进数组即可排序
        public static void Sort(int[] arr)
        {
            int n = arr.Length;
            int[] temp = new int[n];
            Sort(arr, temp, 0, n - 1);
        }

        //递归使用归并排序,对arr[l...r]的范围进行排序
        private static void Sort(int[] arr,int[] temp,int l,int r)
        {
            
            if (l >= r) return;//可以在这里进行优化,看下面的Sort2

            //int mid = (r + l) / 2;
            int mid = l + (r - l) / 2;
            //Console.WriteLine("mid = {0}", mid);

            Sort(arr, temp, l, mid);        //将左半边排序
            Sort(arr, temp, mid + 1, r);    //将右半边排序
            Merge(arr, temp, l, mid, r);    //归并结果
        }

        // 将arr[l...mid]和arr[mid+1...r]两部分有序排列进行归并
        private static void Merge(int[] arr,int[] temp,int l,int mid ,int r)
        {
            //Console.WriteLine("Merge({0},{1},{2})", l, mid, r);

            int i = l;
            int j = mid + 1;
            int k = l;

            //左右半边都有元素(将小的放到temp数组中)
            while(i<=mid && j <= r)
            {
                if(arr[i] < arr[j])
                    temp[k++] = arr[i++];
                else //arr[i] >= arr[j]
                    temp[k++] = arr[j++];
            }

            //左半边还有元素,右半边用尽(取左半边的元素)
            while (i <= mid)
                temp[k++] = arr[i++];

            //右半边还有元素,左半边用尽(取右半边的元素)
            while (j <= r)
                temp[k++] = arr[j++];

            //将temp数组拷贝回给arr数组,完成arr排序
            for (int z = l; z <= r; z++)
                arr[z] = temp[z];
        }
    }

6、归并排序(优化),在递归终止条件处处理,数组长度小时使用插入排序即可

//时间复杂度O(nlogn)
    //空间复杂度O(n)需要借助一个同样长度的辅助数组进行排序
    class MergeSort2
    {
        //用户调用的排序方法传进数组即可排序
        public static void Sort(int[] arr)
        {
            int n = arr.Length;
            int[] temp = new int[n];
            Sort(arr, temp, 0, n - 1);
        }

        //递归使用归并排序,对arr[l...r]的范围进行排序
        private static void Sort(int[] arr, int[] temp, int l, int r)
        {

            if (r - l + 1 <= 15)
            {
                InsertSort.Sort1(arr, l, r);
                return;
            }

            int mid = l + (r - l) / 2;
            Sort(arr, temp, l, mid);        //将左半边排序
            Sort(arr, temp, mid + 1, r);    //将右半边排序

            if (arr[mid] > arr[mid + 1])
                Merge(arr, temp, l, mid, r);    //归并结果
        }

        // 将arr[l...mid]和arr[mid+1...r]两部分有序排列进行归并
        private static void Merge(int[] arr, int[] temp, int l, int mid, int r)
        {
            int i = l;
            int j = mid + 1;
            int k = l;

            //左右半边都有元素(将小的放到temp数组中)
            while (i <= mid && j <= r)
            {
                if (arr[i] < arr[j])
                    temp[k++] = arr[i++];
                else //arr[i] >= arr[j]
                    temp[k++] = arr[j++];
            }

            //左半边还有元素,右半边用尽(取左半边的元素)
            while (i <= mid)
                temp[k++] = arr[i++];

            //右半边还有元素,左半边用尽(取右半边的元素)
            while (j <= r)
                temp[k++] = arr[j++];

            //将temp数组拷贝回给arr数组,完成arr排序
            for (int z = l; z <= r; z++)
                arr[z] = temp[z];
        }
    }

7、快速排序

 //快速排序 O(nlogn)
    class QuickSort1
    {
        public static void Sort(int[] arr)
        {
            int n = arr.Length;
            Sort(arr, 0, n - 1);
        }

        private static void Sort(int[] arr,int l,int r)
        {
            if (r - l + 1 <= 15)
            {
                InsertSort.Sort1(arr, l, r);
                return;
            }

            int v = arr[l];

            int j = l; // arr[l+1...j] < v  arr[j+1...i-1] > v

            for (int i = l+1; i <= r; i++)
            {
                if(arr[i] < v)
                {
                    j++;
                    Swap(arr, i, j);
                }
            }

            Swap(arr, l, j);
            Sort(arr, l, j - 1);
            Sort(arr, j + 1, r);
        }

        private static void Swap(int[] arr,int i,int j)
        {
            int e = arr[i];
            arr[i] = arr[j];
            arr[j] = e;
        }
    }

8、快速排序(优化),在递归终止条件处处理,数组长度小时使用插入排序即可

 class QuickSort2
    {
        private static Random rd = new Random();

        public static void Sort(int[] arr)
        {
            int n = arr.Length;
            Sort(arr, 0, n - 1);
        }

        private static void Sort(int[] arr, int l, int r)
        {
            if (r - l + 1 <= 15)
            {
                InsertSort.Sort1(arr, l, r);
                return;
            }

            int p =l + rd.Next(r - l + 1);

            Swap(arr, l, p);

            int v = arr[l];

            int j = l; // arr[l+1...j] < v  arr[j+1...i-1] > v

            for (int i = l + 1; i <= r; i++)
            {
                if (arr[i] < v)
                {
                    j++;
                    Swap(arr, i, j);
                }
            }

            Swap(arr, l, j);
            Sort(arr, l, j - 1);
            Sort(arr, j + 1, r);
        }

        private static void Swap(int[] arr, int i, int j)
        {
            int e = arr[i];
            arr[i] = arr[j];
            arr[j] = e;
        }
    }

9、快速排序(优化), 对标定元素随机化处理,对排序有序性很强的数组会得到很大的优化

class QuickSort3
    {
        private static Random rd = new Random();

        public static void Sort(int[] arr)
        {
            int n = arr.Length;
            Sort(arr, 0, n - 1);
        }

        private static void Sort(int[] arr,int l ,int r)
        {
            //对小规模的数组使用插入排序,避免频繁的递归调用
            if (r - l + 1 <= 15)
            {
                InsertSort.Sort1(arr, l, r);
                return;
            }

            //随机化处理,对排序有序性很强的数组会得到很大的优化
            int p = l + rd.Next(r - l + 1);

            Swap(arr, l, p);

            int v = arr[l];    //标定元素v

            int lt = l;        // arr[l+1...lt] < v
            int gt = r + 1;    // arr[gt...r] > v
            int i = l + 1;     // arr[lt+1...i-1] == v

            //往三个区间填充元素
            while(i < gt)
            {
                if(arr[i] < v)
                {
                    lt++;
                    Swap(arr, i, lt);
                    i++;
                }
                else if(arr[i] > v)
                {
                    gt--;
                    Swap(arr, i, gt);
                }
                else //arr[i]==v
                {
                    i++;
                }
            }

            //跳出while循环填充完毕后,把标定元素放到合适位置
            Swap(arr, l, lt);

            Sort(arr, l, lt - 1);  //将左半部分arr[l...lt-1]排序
            Sort(arr, gt, r);      //将右半部分arr[gt...r]排序

        }

        private static void Swap(int[] arr,int i,int j)
        {
            int e = arr[i];
            arr[i] = arr[j];
            arr[j] = e;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xyz_sky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值