JavaSE学习总结(十一)常见八大排序算法/冒泡排序/选择排序/直接插入排序/希尔排序/归并排序/快速排序/基数排序/堆排序

排序

一、冒泡排序

(一)原理

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

在这里插入图片描述

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        int t=0;
        for (int i = 0; i < a.length-1; i++) { //外层循环用于定义排序次数
            for(int j = 0;j < a.length-i-1; j++){ //j < a.length-i-1 定义每次排序比较的次数
                if(a[j]>a[j+1]){
                    t=a[j];
                    a[j]=a[j+1];
                    a[j+1]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

在这里插入图片描述

二、选择排序

(一)原理

第一种:从0索引开始,逐个和后面的所有元素进行比较,小的往前放,第一轮排序完后,最小的元素出现在了最小索引处;第二轮排序,从1索引开始…
在这里插入图片描述
第二种:第一次设定起始位置的元素为最小(大)元素,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的首部。以此类推,直到全部待排序的数据元素的个数为零。

(二)代码实现

第一种

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        int t=0;
        for (int i = 0; i < a.length-1; i++) { //外层循环定义排序次数 i为每次选择排序选择的元素的索引
            for(int j = i+1;j < a.length; j++){ //每次从索引为i的元素后开始比较
                if(a[i]>a[j]){
                    t=a[i];
                    a[i]=a[j];
                    a[j]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

在这里插入图片描述
第二种

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        for (int i = 0; i < a.length-1; i++) {//确定每次开始的位置
            int min=a[i];//假设每次起始的元素就是最小值
            int flag=i;//标记最小值所在的位置
            for(int j=i+1;j<a.length;j++){
                if(a[j]<min){//从开始索引向后一个个和min比较,再把最小值存放到min,并更新flag标记
                    min=a[j];
                    flag=j;
                }
            }
            if(min!=a[i]){//如果min和起始的索引的元素值不一致了,则交换min所在的索引元素和起始索引的元素
                a[flag]=a[i];
                a[i]=min;
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
}

在这里插入图片描述

三、直接插入排序

(一)原理

直接插入排序,是一种最简单的排序方法。他的基本操作是将一个记录插入到一个长度为m 的有序表中,使之仍保持有序,从而得到一个新的长度为m+1的有序列表。假设有一组无序元素{k1,k2…,kn},排序开始就认为k1是一个长度为1的有序序列,让k2按照大小顺序插入上述k1这个有序序列,使之成为一个表长为2的有序序列,然后让k3按照大小顺序插入上述表长为2的有序序列,使之成为一个表长为3的有序序列,以此类推,最后让kn插入表长为n-1的有序序列,得到一个表长为n的有序序列。

例如:
49,38,65,97,76,13,27 原始数据
[49],38,65,97,76,13,27 从1索引开始
[38,49], ,65,97,76,13,27
[38,49,65] 97,76,13,27
[38,49,65,97] 76,13,27
[38,49,65,76,97]13,27
[13,27,38,49,65,76,97],27
[13,27,27,38,49,65,76,97]

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        for (int i = 1; i < a.length; i++) {//外层循环定义轮次
            for(int j=i;j>0;j--){//里层就是循环让当前元素和上一个有序列表中的每个元素比较,进行位置交换,使之仍保持有序
                if(a[j]<a[j-1]){
                    int t=a[j];
                    a[j]=a[j-1];
                    a[j-1]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

在这里插入图片描述

四、希尔排序

(一)原理

其实希尔排序也是一种插入排序。
希尔排序又称缩小增量排序。它先将原数组按增量(间隔)ht分组,每个分组按直接插入法排序。排完后用下一个增量ht/2再进行分组,再直接插入排序。直到ht=1时插入排序完成后,数组有序。
关键:选择合适的增量。
在这里插入图片描述
主要特点

  • 每一趟以不同的增量进行插入排序,当增量ht较大时,被移动的记录是跳跃式进行的,到最后一趟排序时(ht=1),大部分记录已经有序,不需要多少移动,所以提高了排序的速度。
  • 希尔排序的时间复杂度分析与选择的增量有关系,它是不稳定的排序方法。

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        for (int d = a.length / 2; d >= 1; d = d / 2) {//最普通的增量选择就是使用数组长度的一半 比较完一轮后改变增量
            for (int i = d; i < a.length; i++) {//其实直接插入排序就是增量为1的希尔排序
                for (int j = i; j >= d; j = j - d) {//里层就是循环让当前元素和上一个有序列表中的每个元素比较,进行位置交换,使之仍保持有序
                    if (a[j] < a[j - d]) {
                        int t = a[j];
                        a[j] = a[j - d];
                        a[j - d] = t;
                    }
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
}

在这里插入图片描述

增量的合理选择
最普通的选择就是使用数组长度的一半
这种增量从效率上来说,不是非常好

对于特别大的数组如果增量(间隔)还是选择数组长度的一半,并不断除2直到增量为1,那么比较的次数也会非常多,效率低。我们可以用Knuth序列来进行增量的选择。

Knuth序列:1,4,13,40,… ,3*d+1(d为上一个增量的大小)

举例来说,有一个包含1000个数据的无序数组,首先在一个循环中使用序列的生成公式来计算出最初的增量:d值最初被赋为1,然后应用公式d=3*d+1生成序列1,4,13,40,121,364,1093…当间隔大于数组大小的时候,这个过程停止。对于一个含有1000个数据的数组,1093就太大了。因此,使用序列的364作为最大的数字来开始这个排序过程。然后,每完成一次排序全程的外部循环,用前面提供的此公式倒推式来减小间隔:d=(d-1)/3。这个倒推的公式生成逆置的序列364,121,40,13,4,1。从364开始,以每一个数字作为增量进行排序。当数组用1增量排序完后,算法结束。

希尔排序比插入排序快很多,它是基于什么原因呢? 当d值大的时候,数据项每一趟排序需要移动元素的个数很少,但数据项移动的距离很长。这是非常有效率的。当d逐渐减小时,此时数据项已经大致有序了,这时要移动的元素也相对少了,这相比于插入排序可以更有效率。

使用Knuth序列的希尔排序

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};

        int startIncrement = 1;//设置起始增量
        while (startIncrement < (a.length - 1)/3) {//找到符合该无序数组长度的合理增量
            startIncrement = 3 * startIncrement + 1;
        }
        System.out.println(startIncrement);

        for (int d = startIncrement; d >= 1; d = (d - 1) / 3) {
            for (int i = d; i < a.length; i++) {
                for (int j = i; j >= d; j = j - d) {
                    if (a[j] < a[j - d]) {
                        int t = a[j];
                        a[j] = a[j - d];
                        a[j - d] = t;
                    }
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
}

在这里插入图片描述

五、归并排序

(一)原理

归并排序(Merge Sort)就是利用归并的思想实现排序的方法。它的原理是假设初始序列有N个记录,则可以看成是N个有序的子序列,每个子序列的长度为1,然后两两归并,得到 N/2 个长度为2或1的有序子序列,再两两归并…
如此重复,直至得到一个长度为N的有序序列为止,这种排序方法称为2路归并排序。

1.分而治之

归并排序,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之

在这里插入图片描述

2.合并有序的子序列

再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。

在这里插入图片描述

在这里插入图片描述

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        chaiFen(a,0,a.length-1);
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
    private static void chaiFen(int[] a,int startIndex,int endIndex) {//递归拆分,拆分好后逐步归并
        //计算中间索引
        int middleIndex=(startIndex+endIndex)/2;
        if(startIndex<endIndex){
            //递归拆分左边
            chaiFen(a,startIndex,middleIndex);
            //递归拆分右边
            chaiFen(a,middleIndex+1,endIndex);
            //归并
            merge(a,startIndex,middleIndex,endIndex);
        }
    }
    private static void merge(int[] a,int startIndex,int middleIndex,int endIndex) {
        int[] t=new int[endIndex-startIndex+1];//定义临时数组
        int i=startIndex;//定义第一个数组的开始索引
        int j=middleIndex+1;//定义第二个数组的开始索引
        int index=0;//定义临时数组的开始索引
        //遍历数组进行大小比较,使之有序放入临时数组
        while(i<=middleIndex&&j<=endIndex){
            if(a[i]<=a[j]){
                t[index]=a[i];
                i++;
                index++;
            }else {
                t[index]=a[j];
                j++;
                index++;
            }
        }
        /*因为两个数组的的元素个数,不是均等的,通过上面循环比较完后会有
        剩余元素,可能第一个数组元素会有剩余,也可能第二个数组元素会有剩余
         */
        while(i<=middleIndex){
            t[index]=a[i];
            i++;
            index++;
        }
        while(j<=endIndex){
            t[index]=a[j];
            j++;
            index++;
        }
        //然后我们遍历临时数组,将临时数组中的元素,放置到原数组中
        for (int k = 0; k < t.length; k++) {
            //注意这里k要加上起始索引
            a[k + startIndex] = t[k];
        }
    }
}

在这里插入图片描述

六、快速排序

(一)原理

  1. 先从数列中取出一个数作为基准数。
  2. 将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  3. 再对左右区间重复第二步,直到各区间只有一个数。

举例
在这里插入图片描述
解析:首先将第一个元素6作为基准数,起初i和j索引分别在数组的首和尾,从j开始从后向前找比基准数6小的值,找到后停下,于是j在值5处停下;接着,i开始从前向后找比基准数大的数,找到后停下,于是i在值为7处停下,然后交换5和7。再接着,j继续向前移,找到比基准数小的4,然后i继续向后移,找到比基准数大的9,将4和9交换。接着,j继续前移,找到比基准数小的3,i再开始后移,也到了3的位置,i和j重合了,于是,将3和基准数6交换(i和j重合,就将基准数和该处元素交换)。至此,基准数6就排到了自己正确的位置,然而6两边的数还是无序的,因此又拆分成两个数组,重复上述的操作,直到所有的数都归位为止。

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        quickSort(a, 0, a.length - 1);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
    private static void quickSort(int[] a, int startIndex, int endIndex) {
        if (startIndex < endIndex) {
            //获取归位后的基准数形成的左右分区的索引
            int index = getIndex(a, startIndex, endIndex);
            //对左右两个分区 再进行同样的步骤 ,即递归调用
            quickSort(a, startIndex, index - 1);
            quickSort(a, index + 1, endIndex);
        }
    }
    private static int getIndex(int[] a, int startIndex, int endIndex) {
        int index = startIndex;//定义基准数的索引
        int i = startIndex;
        int j = endIndex;
        int t = 0;//临时变量
        while (i < j) {
            while (i < j && a[j] >= a[index]) {//从右往左比较,找到比基准数小的数
                j--;
            }
            while (i < j && a[i] <= a[index]) {//从左往右比较,找到比基准数大的数
                i++;
            }
            //交换两个数
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
        //此时i=j,交换基准数和a[i]
        t = a[i];
        a[i] = a[index];
        a[index] = t;
        return i;//返回此时基准数所在的索引
    }
}

在这里插入图片描述

七、基数排序

(一)原理

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。
举例:先将原始数组的元素按个位数以在数组中的顺序分别放进对应的“桶”中,例如750个位数为0,则放进0的“桶”中。所有数放完后再按放入桶中的顺序取出来,再进行十位数的比较,重复以上操作,再进行百位数的比较…
在这里插入图片描述
在这里插入图片描述

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        //基数排序:分配再收集,元素之间不比较大小
        int[] a = {1, 2, 45, 90, 43, 65, 87, 99, 234, 987, 154, 92, 12,19000,1768,2909};
        //进行基数排序
        sortArray(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
    private static void sortArray(int[] a) {
        //定义一个二维数组,里面放十个桶
        int[][] tempArr = new int[10][a.length];
        //定义一个一维数组,用于统计十个桶中各有多少元素
        int[] counts = new int[10];
        //获取数组中的最大值
        int max = getMax(a);
        //获取最大数的位数,确定我们要分配收集的轮次
        int len = String.valueOf(max).length();
        for (int i = 0, n = 1; i < len; i++, n *= 10) {
            for (int j = 0; j < a.length; j++) {
                int ys = a[j] / n % 10;//获取每个位上的数字
                //根据每个位上的数字放入对应的桶中
                tempArr[ys][counts[ys]++] = a[j];
            }
            //每一轮排序完后,按顺序取出桶中的数据
            int index = 0;
            for (int k = 0; k < counts.length; k++) { //k代表桶0-9
                if (counts[k] != 0) {
                    for (int h = 0; h < counts[k]; h++) {
                        //取出桶中的数据,放回原数组
                        a[index] = tempArr[k][h];
                        index++;
                    }
                    //取完之后,清除上次统计的个数,以进行下一轮排序
                    counts[k]=0;
                }
            }
        }
    }
    //找出数组中的最大数,判断其位数以确定排序轮次
    private static int getMax(int[] a) {
        int max = a[0];
        for (int i = 1; i < a.length; i++) {
            if (a[i] > max) {
                max = a[i];
            }
        }
        return max;
    }
}

在这里插入图片描述
细心的朋友可能会问:如果数组中有负数怎么办?
那么我们可以首先找到数组中的最小负数值,然后让所有数字加上这个负数值的绝对值,保证所有数字都为非负,再进行基数排序,最后再让所有数字减去刚刚加上的绝对值就好了。

public class MyTest11 {
    public static void main(String[] args) {
        //基数排序:分配再收集,此排序方法元素之间不比较大小
        int[] a = {1, 2, 45, -90, 43, 65, -87, 99, -234, 987, -154, 92, 12,19000,1768,2909};
        int min = getMin(a);
        if(min<0){
            for (int i = 0; i < a.length; i++) {
                a[i]=a[i]+Math.abs(min);
            }
            //进行基数排序
            sortArray(a);
            for (int i = 0; i < a.length; i++) {
                a[i]=a[i]-Math.abs(min);
                System.out.print(a[i] + " ");
            }
        }else{
            //进行基数排序
            sortArray(a);
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i] + " ");
            }
        }
    }
    private static void sortArray(int[] a) {
        //定义一个二维数组,里面放十个桶
        int[][] tempArr = new int[10][a.length];
        //定义一个一维数组,用于统计十个桶中各有多少元素
        int[] counts = new int[10];
        //获取数组中的最大值
        int max = getMax(a);
        //获取最大数的位数,确定我们要分配收集的轮次
        int len = String.valueOf(max).length();
        for (int i = 0, n = 1; i < len; i++, n *= 10) {
            for (int j = 0; j < a.length; j++) {
                int ys = a[j] / n % 10;//获取每个位上的数字
                //根据每个位上的数字放入对应的桶中
                tempArr[ys][counts[ys]++] = a[j];
            }
            //每一轮排序完后,按顺序取出桶中的数据
            int index = 0;
            for (int k = 0; k < counts.length; k++) { //k代表桶0-9
                if (counts[k] != 0) {
                    for (int h = 0; h < counts[k]; h++) {
                        //取出桶中的数据,放回原数组
                        a[index] = tempArr[k][h];
                        index++;
                    }
                    //取完之后,清除上次统计的个数,以进行下一轮排序
                    counts[k]=0;
                }
            }
        }
    }
    //找出数组中的最大数,判断其位数以确定排序轮次
    private static int getMax(int[] a) {
        int max = a[0];
        for (int i = 1; i < a.length; i++) {
            if (a[i] > max) {
                max = a[i];
            }
        }
        return max;
    }
    //找出数组中的最小数
    private static int getMin(int[] a) {
        int min = a[0];
        for (int i = 1; i < a.length; i++) {
            if (a[i] < min) {
                min = a[i];
            }
        }
        return min;
    }
}

在这里插入图片描述

八、堆排序

声明:本节转载自Fuzz_的博客https://blog.csdn.net/qq_36186690/article/details/82505569

(一)原理

在讲堆排序之前介绍几个概念:

  • 叶子结点:一棵树当中没有子结点(即度为0)的结点称为叶子结点
  • 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为k,且结点总数是(2^k) -1 ,则它就是满二叉树。(除最后一层无任何子结点外,每一层上的所有结点都有两个子结点的二叉树。)
  • 完全二叉树:若一个二叉树有k层,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,且第k 层所有的结点都连续集中在最左边,这就是完全二叉树。满二叉树是完全二叉树的一种。

堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆的两种表现形式:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:
在这里插入图片描述

同时,我们对大顶堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

在这里插入图片描述
我们发现,一个索引为i的结点,它的左右结点的索引分别为2*i+1和2*i+2。

该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

大顶堆:arr[i] >= arr[2*i+1] && arr[i] >= arr[2*i+2]

小顶堆:arr[i] <= arr[2*i+1] && arr[i] <= arr[2*i+2]

堆排序基本思想:
  1. 将待排序列构成一个大顶堆(或者小顶堆),升序用大顶堆,降序用小顶堆;
  2. 将堆顶元素与堆尾元素交换,并断开(从待排序列中移除)堆尾元素,该元素就为最大(小)值。
  3. 用剩下的元素重新构建大顶堆(小顶堆)。
  4. 重复2~3,直到待排序列中只剩下一个元素。
步骤演示:

步骤一 将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。

a.假设给定无序序列结构如下

在这里插入图片描述

2.此时我们从第一个非叶子结点开始(叶子结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。由于[6,9,5]中9最大,因此6和9交换。

在这里插入图片描述

4.找到第二个非叶子结点4,由于[4,9,8]中9元素最大,4和9交换。

在这里插入图片描述

这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。

在这里插入图片描述

此时,我们就将一个无需序列构造成了一个大顶堆。

步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

a.将堆顶元素9和末尾元素4进行交换
在这里插入图片描述

b.重新调整结构,使其继续满足大顶堆定义
在这里插入图片描述

c.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8.

在这里插入图片描述

后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
在这里插入图片描述

(二)代码实现

public class HeapSort {
    public static void main(String []args){
        int []arr = {1, 2, 45, -90, 43, 65, -87, 99, -234, 987, -154, 92, 12,19000,1768,2909};
        sort(arr);
        System.out.print("排序后:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
    public static void sort(int []arr){
        //1.构建大顶堆
        for(int i=arr.length/2-1;i>=0;i--){//非叶子结点的查找顺序:从下至上
            //从上至下,从左至右调整结构
            adjustHeap(arr,i,arr.length);
        }
        //2.调整堆结构+交换堆顶元素与末尾元素
        for(int j=arr.length-1;j>0;j--){
            swap(arr,0,j);//将堆顶元素与末尾元素进行交换
            adjustHeap(arr,0,j);//重新对堆进行调整  因为其他元素都是有序的,就堆顶被换过 无序,因此从0索引开始重新构建大顶堆
        }
    }
    /**
     * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
     * @param arr  待调整的数组
     * @param i 表示当前非叶子结点在数组中的索引
     * @param length 表示有多少个元素需要继续调整, length在不断减小
     */
    public static void adjustHeap(int []arr,int i,int length){
        for(int k=i*2+1;k<length;k=k*2+1){//从i结点的左子结点开始,也就是2i+1处开始
            //下面这段代码用于找到i结点的最大的子结点 如果左子结点小于右子结点,k指向右子结点  k+1>=length就溢出 没必要比较了
            if(k+1<length && arr[k]<arr[k+1]){
                k++;
            }
            if(arr[k] >arr[i]){//如果子结点大于父结点,交换父子结点
                swap(arr,i,k);
                // 如果子结点更换了,那么,以子结点为根的子树会受到影响,所以,循环对子结点所在的树继续进行判断
                i = k;
            }else{
                break;
            }
        }
    }
    /**
     * 交换元素
     * @param arr 需要交换元素所在的数组
     * @param a   需要交换的元素索引
     * @param b   需要交换的元素索引
     */
    public static void swap(int []arr,int a ,int b){
        int temp=arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

在这里插入图片描述

总结:八种排序的性能比较

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值