数据结构与算法笔记-------选择排序

选择排序

基本介绍

选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。

排序思想

选择排序(select sorting) 也是一种简单的排序方法。它的基本思想是:

第一次:从一个array数组中找到最小值与array[0]交换,也就是说不是像冒泡那样找到小的就交换,而是遍历了数组,找到最小的和array[0]交换,一次只发生一次交换

第二次:从array数组的array[1]~~~array[n-1]中找到最小值,与array[1]交换,这个过程中也是只发生一次交换

第三次:array[2]变成最小值。。。。依次类推

总共通过n-1次,得到一个按排序码从小到大排序的有序序列

img

思路

第一轮:将第一个位置当成最小数,开始循环遍历余下数组,比他小的更新成最小值,再往后找比现在这个还小的,一轮下来,找到最小的,开始交换

第二轮:将第二个位置当成最小数,开始循环遍历余下数组,往后面比较,发现比他小的,在更新最小值,再往后,找到剩余数中最小的数,遍历完之后,和第一个位置交换

第三轮:同理,从第三个位置开始

….

直到n-1轮

请听题:

现有科大学生十位,颜值分别是[100,10,35,24,16,79,4,2,57,80],请使用选择排序从低到高进行排序

代码

推导过程:

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 21:32
 * @Description TODO
 * @pojectname 简单选择排序
 */
public class SelectSort {
    
    
    public static void main(String[] args) {
    
    
        int[] array = {
    
    100,10,35,24,16,79,4,2,57,80};
        selectSort(array);
    }
    //选择排序算法
    public static void selectSort(int[] array){
    
    
        //逐步推到方式
        //第一轮排序
        //原始数组[100,10,35,24,16,79,4,2,57,80]
        //结果:[2,10,35,24,16,79,4,100,57,80]
        int minIndex = 0;//用来存放,最小值的下标
        int min = array[0];//假定现在最小值是数组第一个  也充当了中间值,来交换
        for (int i = 0+1; i < array.length ; i++) {
    
    
            if (min > array[i]){
    
    //说明我们的假定最小值不是最小值
                min = array[i];  //重置最小值
                minIndex = i;   //重置最小值索引
            }
        }
        //循环结束,开始交换
        if (minIndex != 0) {
    
    
            array[minIndex] = array[0];
            array[0] = min;
        }
        System.out.println("第一轮后:"+ Arrays.toString(array));
        //第一轮后:[2, 10, 35, 24, 16, 79, 4, 100, 57, 80]

        //第二轮排序
        minIndex = 1;//用来存放,最小值的下标
        min = array[1];//假定现在最小值是数组第一个  也充当了中间值,来交换
        for (int i = 1+1; i < array.length ; i++) {
    
    
            if (min > array[i]){
    
    //说明我们的假定最小值不是最小值
                min = array[i];  //重置最小值
                minIndex = i;   //重置最小值索引
            }
        }
        //循环结束,开始交换
        if (minIndex != 1) {
    
    
            array[minIndex] = array[1];
            array[1] = min;
        }
        System.out.println("第二轮后:"+ Arrays.toString(array));
        //第二轮后:第二轮后:[2, 4, 35, 24, 16, 79, 10, 100, 57, 80]
        //依次类推
    }
}

在推导过程中,我们发现我们每次for循环之前,开始的标记,比上一轮for循环开始的位置+1了

那么我们可以用for循环来解决

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 21:32
 * @Description TODO
 * @pojectname 简单选择排序
 */
public class SelectSort {
    
    
    public static void main(String[] args) {
    
    
        int[] array = {
    
    100,10,35,24,16,79,4,2,57,80};
        System.out.println("排序前"+Arrays.toString(array));
        selectSort(array);
        System.out.println("排序后"+Arrays.toString(array));
    }
    //选择排序算法
    public static void selectSort(int[] array){
    
    
        for (int i = 0; i < array.length -1 ; i++) {
    
    
            int minIndex = i;
            int min = array[i];
            for (int j = i+1; j <array.length ; j++) {
    
    
                if (min > array[j]){
    
    //说明假定的最小值不是最小
                    min = array[j];//重置min
                    minIndex = j;//重置最小值下标
                }
            }
            //交换
            if (minIndex != i){
    
    
                array[minIndex] = array[i];
                array[i] = min;
            }
            System.out.println("第"+i+"轮排序的结果是");
            System.out.println(Arrays.toString(array));
        }
    }
}

我们来语言加深一下记忆:

外层循环控制第几轮排序,内层循环是用来控制我们的排序开始的位置

其中,优点在哪?我们发现我们的数据交换的方式跟我们的冒泡排序不一样了,因为这里是一次交换,不像是我们的冒泡排序那样,每次达到要求就交换,所以我们的选择排序,用了最小值下标这个中间辅助变量,用来只发生一次变化

那有人会觉得,若是我第N轮恰好不用交换呢?我们发现我们交换的时候多了一层if判断,这个if判断就是用来判断,当前最小值下标是不是我们一开始假定的最小值的下标,如果不是在交换,是的话就直接输出了,不发生交换,算是一个小优化

然后我们测一测选择排序去排序一个array[80000]数组的时间,我们发现就单单2秒钟或者3秒钟,确实比冒泡排序快多了

猜你喜欢

转载自blog.csdn.net/qq_22155255/article/details/111501683