这里建议使用电脑浏览,手机可能观看困难

序.简单介绍:

        选择排序是一种简单直观的排序算法,先通过外侧循环决定已排序区域和未排序区域,再由内侧循环通过重复遍历未排序部分,每次选择最小(或最大)元素,放到已排序部分的末尾来做到排序一组乱序数据的效果。其时间复杂度为 O(n²),适用于小规模数据排序。

一.排序过程: 

  1. 初始状态划分
    将数组分为已排序部分(初始为空)和未排序部分(初始为整个数组)。
  2. 查找最小元素
    遍历未排序部分,找到最小元素的索引。
  3. 交换元素位置
    将最小元素与未排序部分的第一个元素交换,将其纳入已排序部分。
  4. 重复操作
    重复上述步骤,每次缩小未排序部分的边界,直至所有元素排序完成。
  5. 演示:

  6. 这里演示从大到小的选择排序实际运行的排序逻辑:
    *
    * -选择排序的过程:
    *
    EG:  7   3   9   2   5
    *

    * 每一轮循环,第一轮: i = 0
    * 初始------<i指向7,即arr[0]>-------<j指向3,即arr[1]>--------------------------
    * 开始>      7<-arr[i]  |   3<-arr[j]   9               2                  5
    * 第一步=> 判断当前arr[i]与arr[j]的大小关系,若arr[i] < arr[j],则进行交换,这里不交换
    *
    * 不交换>    7<-arr[i]  |   3<-arr[j]   9               2                  5
    * 第二步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移>     7<-arr[i]  |   3           9<-arr[j]       2                 5
    * 第三步=> 此处由于9(arr[j])>7(arr[i]),交换两者位置
    *
    * 交换后>    9<-arr[i]  |   3           7<-arr[j]       2                 5
    * 第四步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移>     9<-arr[i]  |   3           7               2<-arr[j]        5
    * 第五步=> 这里arr[i] > arr[j],故不做交换
    *
    * 不交换>    9<-arr[i]  |  3           7               2<-arr[j]        5
    * 第六步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移>    9<-arr[i]  |   3           7               2               5<-arr[j]
    * 第七步=> 这里arr[i] > arr[j],故不做交换
    *
    * 不交换>    9<-arr[i]  |   3           7               2               5<-arr[j]
    * 第八步=> j向后选取 -> (j >= 数组长度) -> j所在for循环结束,进入第二轮循环
    *
    *=================================================================
    * 至此,第一轮循环结束,未排序区域的一个最大值(9)被排入了已排序区 -> i++ -> i = 1
    *=================================================================
    * 第二轮: i = 1
    * 初始------<i指向3,即arr[1]>-------<j指向7,即arr[2]>--------------
    * 开始>     9     3<-arr[i]    |      7<-arr[j]         2             5
    * 第一步=> 此处由于7(arr[j])>3(arr[i]),交换两者位置
    *
    * 交换后>   9     7<-arr[i]     |      3<-arr[j]        2             5
    * 第二步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移>    9     7<-arr[i]     |      3               2<-arr[j]      5
    * 第三步=> 这里arr[i] > arr[j],故不做交换
    *
    * 不交换>   9     7<-arr[i]     |      3               2<-arr[j]      5
    * 第四步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移> 9     7<-arr[i]     |       3              2              5<-arr[j]
    * 第五步=> 这里arr[i] > arr[j],故不做交换
    *
    * 不交换> 9     7<-arr[i]    |       3              2              5<-arr[j]
    * 第八步=> j向后选取 -> (j >= 数组长度) -> j所在for循环结束,进入第三轮循环
    *=================================================================
    * 至此,第二轮循环结束,未排序区域的一个最大值(7)被排入了已排序区 -> i++ -> i = 2
    *=================================================================
    * 第三轮: i = 2
    * 初始------<i指向3,即arr[2]>-------<j指向2,即arr[3]>--------------
    * 开始>    9       7       3<-arr[i]     |         2<-arr[j]        5
    * 第一步=> 这里arr[i] > arr[j],故不做交换
    *
    * 不交换> 9       7       3<-arr[i]     |        2<-arr[j]        5
    * 第二步=> j向后选取 -> (j <= 数组长度 - 1) -> j循环继续
    *
    * j后移> 9      7         3<-arr[i]     |         2                5<-arr[j]
    * 第三步=> 此处由于5(arr[j])>3(arr[i]),交换两者位置
    *
    * 交换>    9      7        5<-arr[i]     |         2                3<-arr[j]
    * 第四步=> j向后选取 -> (j >= 数组长度) -> j所在for循环结束,进入第四轮循环
    *=================================================================
    * 至此,第三轮循环结束,未排序区域的一个最大值(5)被排入了已排序区 -> i++ -> i = 3
    *=================================================================
    * 第四轮: i = 3
    * 初始------<i指向2,即arr[3]>-------<j指向5,即arr[4]>--------------
    * 开始> 9          7         5         2<-arr[i]    |      3<-arr[j]
    * 第一步=> 此处由于3(arr[j])>2(arr[i]),交换两者位置
    *
    * 交换>   9          7         5          3<-arr[i]    |      2<-arr[j]
    * 第四步=> j向后选取 -> (j >= 数组长度) -> j所在for循环结束,进入第五轮循环
    *=================================================================
    * 至此,第四轮循环结束,未排序区域的一个最大值(3)被排入了已排序区 -> i++ -> i = 4
    * 此时,i >= 数组长度-1 , i循环结束
    * 排序结束!

    *=================================================================
    *排序结果: 9        7        5        3        2  
    */

二.代码实现(这里使用Java语言实现):

//选择排序算法主体:
public static void select_sort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] > arr[i]) {
                MyMath.swap(arr, j, i);
            }
        }
    }
}
 

MyMath.swap(arr, j, i); 是我自己写的一个交换元素的方法,代码如下:

public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
 

三.性能测试

        使用了如下代码生成的随机数组,分别处理100,1000以及10000长度的乱序数组数据:

public class RandomArrayGenerator {

    /**
     * 生成指定长度的随机数组,元素范围在0-50000之间
     * @param length 数组长度
     * @return 随机整数数组
     */
    public static int[] getRandomArr(int length) {
        int[] arr = new int[length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 50000);
        }
        return arr;
    }
}
 

  运行结果:

  •                    数组长度 100: 运行时间 0.0012 秒
    •                 数组长度 1000: 运行时间 0.0824 秒
      •                 数组长度 10000: 运行时间 7.6543 秒

结论:

        选择排序在面对小规模乱序数据排序时拥有不错的性能,但是由于其重复遍历的特性,会导致它的运行效率受到数组长度的影响(数组长度越长,运行效率越慢),所以在面对较大规模数据时,它的运行效率会呈现骤然降低的趋势.

尾.个人想说的话:

我是一名学习JAVA等编程语言的普通学生,如果我的这篇文章帮助到了你,我很开心,同时如果我的文章有问题,请各位发现后对我所说的有问题的部分做出修改和指正(请详细一些),避免他人看到造成误导,欢迎各位在评论区讨论、补充、以及纠正错误。

#如果觉得博客内容对你有帮助的话可以支持一下我的其它博客:

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐