三种常见排序算法

冒泡排序

介绍:

在冒泡排序中,只有当两个元素不满足条件的时候才会需要交换,所以只有后一个元素大于前一个元素时才进行交换,这时的冒泡排序是一个稳定的排序算法。

步骤:

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

本质上是一个数组经过每轮将最大/第二大/第三大(以此类推)逐个将数放在最后/次后的算法

img

 

这里将{5,1,2,4,9,3}通过第一次排序后,将最大的9通过换位放在最后,同时一个数在n个数中比较大小,不需要和自身进行比较,因此只需要n-1次,在数组中也就是array.length-1次

在内部循环中,也就是第二轮循环寻找第二大数值时,最大的数与第二大的数字在第一轮已经进行过比较,所以可以省略比较步骤

当i=2时,也就是外层循环进行第三轮比较时,(第三大的数字),第三大数字与第二大(5和4)在上一轮已经进行过比较,因此省略多余步骤,(5和9依然不需要再次比较)

以此类推,可以发现重复的步骤与i的值相同,因此我们可以得出内部循环的结束条件为:array.length-1-i

程序中执行:

public static void main(String[] args) {
    int []array = {5,1,2,4,9,3};
    for (int i = 0; i < array.length-1; i++) {
        for (int j = 0; j < array.length-1-i; j++) {
            if(array[j]>array[j+1]){
                int tem = array[j];
                array[j] = array[j+1];
                array[j+1] = tem;
            }
        }
    }
    System.out.println(Arrays.toString(array));
}

 

image-20230808114235876

选择排序

步骤:

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。

简单来说就是找到最小数字的索引,与第一个数字交换,然后从第二个开始找到最小的数(此时最小的数是第二小的数,因为最大的已经排到了它的前面)

img

在外循环中,执行的次数是array.lenth-1,因为从数组第二位开始与自身进行比较

内循环开始执行,依次与3以后的数字进行比较,直到有比3还小的数时,记录索引min

否则继续遍后面的数

 

当i=1时,进行第二位数字的寻找,与第一遍不同的是.此时无需再比较数组i=0,(也就是当前索引以前的数字,因为前面的数字当前已经是最小的数).也就是j只需要从i+1开始执行

最终

程序中执行

image-20230808164046300

插入排序

步骤:

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

简单说就是从数组第二个开始默认前面已经拍好序列,记录这一位数组的值,当该数大于前面数时插入,小于前面数时,将前面放索引+1也就是后移,直到该数大于前一位时插入,依次往后

 

img

image-20230808164852907

当i=1的时候,记录前一位的索引为preIndex,可以发现5大于3,此时直接插入,默认前面已经排好序(前面是3),

image-20230808165001901

i=2的时候,此时preIndex的值右移变为1,然后此时需要丛2开始进行插入,当2与5比较时候,小于5,因此5的索引此时后移(不必担心会改变数组原有的值,此时后移,占用的是原来为2索引为2的位置)

之后原来为5的数组的值变成2,preIndex--;(每当数组的值后移的时候-1),此时再次与preIndex的值比较,依然小于前一个数,于是再次preIndex--;并且将3的索引后移;但是此时preIndex为-1,说明以及到达数组边界,因此将2放到该位置变成{2,3,5,8,9,6}

 

image-20230808165724775

i=3,i=4的时候,分别插入8,9;发现都大于preIndex所对应数,因此直接插入

image-20230808170554514

i=5时,6小于9;因此将6向前继续比较,9和8依次后移,preIndex分别为4,3;最终得到排序结果

image-20230808171053918

程序中执行

 

image-20230808174253614

改变while中变量current与array[preIndex]大小关系可以改为升序或者降序;

当前一个值大于当前值时候,执行循环和小于时执行循环这两种情况;(循环内的操作是将前一个值后移,也就是说换句话来说会将较大(较小)的值插入在后面)

多维数组中的三种排序:

在多维数组中对多个数组某一索引进行排序

假设有这样一组二维数组

int[][] scores = {
        {90, 89, 78},
        {59, 40, 100},
        {100, 99, 80},
        {80, 61, 61},
        {60, 100, 99}
};

整体排序:

1.冒泡

如何用冒泡排序对数组中每一个数组进行排序?

循环嵌套可以最基本的完成

i为遍历每一个数组的循环,j是对数组每一个数的排序,k是每个数进行比较的次数

//遍历每一个数组
for (int i = 0; i < scores.length; i++) {
    //进行每个数组内排序(次数为基本的一维数组排序)
    
    for (int j = 0; j < scores[i].length - 1; j++) {
        for (int k = 0; k < scores[i].length-1-j ; k++) {
            if (scores[i][k] < scores[i][k + 1]) {
                int tem = scores[i][k];
                scores[i][k] = scores[i][k + 1];
                scores[i][k + 1] = tem;
            }
        }
​
    }
​
}

得到结果

image-20230810223158677

2.选择排序
for (int i = 0; i < scores.length; i++) {
    for (int j = 0; j < scores[i].length-1; j++) {
        int min =j;
        for (int k = j+1; k < scores[i].length; k++) {
​
            if(scores[i][k]<scores[i][min]){
                min = k;//记录最小值索引
​
            }
​
        }
        int tem = scores[i][j];
        scores[i][j] = scores[i][min];
        scores[i][min] = tem;
​
    }
}

组内某一元素进行排序

首先有这样三组数组

String[] names = {"安琪拉", "王昭君", "蔡文姬", "妲己", "张良"};
String[] courses = {"C++", "JAVA", "PYthon"};
int[][] scores = {
        {90, 89, 78},
        {59, 40, 100},
        {100, 99, 80},
        {80, 61, 61},
        {60, 100, 99}
};
​
//以及对列表输出的方法
 public static void JAVA(int scores[][], String names[], String courses[]) {
        for (int i = 0; i < scores.length; i++) {
            System.out.print(names[i] + " => "); // 输出学生姓名
            for (int j = 0; j < scores[i].length; j++) {
                System.out.print(courses[j] + ":");// 输出课程名称
                System.out.print(scores[i][j]); // 输出课程成绩
                if (j < scores[i].length - 1) {
                    System.out.print(" , ");
                }
            }
            System.out.println();
        }
​
​
    }
1.冒泡排序JAVA成绩

此处两个交换不同点是,成绩是二维数组,而name是一维数组,交换的一个是数组,一个是数组内的元素,这里需要分清楚

以及注意这里j的条件是score.length,因为相当于是把二维数组看成一维数组进行排序,JAVA成绩以外的元素我们不需要关注,也就是说本质上是比较5个Java成绩

for (int i = 0; i < scores.length - 1; i++) {
    for (int j = 0; j < scores.length - 1 - i; j++) {
        if (scores[j][1] < scores[j + 1][1]) {
            //交换数组排序
            int []tem = scores[j];
            scores[j] = scores[j + 1];
            scores[j + 1] = tem;
            //同时交换另一个数组排序
            String nam = names[j];
            names[j] = names[j+1];
            names[j+1] = nam;
        }
    }
}

运行结果

image-20230810231632059

2.选择排序

此处与选择排序不同的一点是,交换的是数组,而不是某一个数,原理依旧是把每一个数组看成若干个数

for (int i = 0; i <scores.length; i++) {
    //最小值
    int min =i;
    for (int j = i+1; j < scores.length; j++) {
​
        if(scores[j][2]>scores[min][2]){
            min = j;
        }
    }
    int []tem =  scores[i];
    scores[i] = scores[min];
    scores[min] = tem;
}
3.插入排序

此处原理不变,唯一改变的是带入数组元素索引,排序依旧是数组之间的排序,至少每个数组看成数字即可

int left = 0;
int right = scores.length - 1;
for (int i = 1; i < scores.length; i++) {
    int index = i - 1;
    int cur = scores[i][0];
    while (index >= 0 && cur > scores[index][0]) {
​
        scores[index + 1][0] = scores[index][0];
        index--;
    }
    scores[index + 1][0] = cur;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值