数据结构和算法:选择排序

219 阅读3分钟

选择排序

1. 算法思想

首先在未排序序列中找到最小元素,存放在未排序序列中的第一位

再从剩余未排序元素中继续寻找最小元素,然后放到在未排序序列中的第一位

以此类推,直到所有元素均排序完毕

2. 特点

  1. 运行时间和输入的数组是没有关系的

比如说 一个有序的数组 和 一个无序的数组所用的时间其实是一样的

  1. 数据移动是最少的

因为每次交换都会改变两个数组元素的值,所以选择排序是N-1次交换。

3. 使用场景

因为算法的时间效率是取决于比较的次数,所以当数组 N 比较小的时候使用。

4. 示例

让我们先来看看案例:

存在一个数组[28,14 ,37 ,42 ,28 ,10]

先进行第一轮的比较:

将 元素中最小的值暂时设置为第一个元素

判断 28 > 14 ,将 14 记录下来

判断 14 < 37 ,保持不变

判断 14 < 42 , 保持不变

判断 14 < 28 , 保持不变

判断 14 > 10 , 将 10 记录下来

10 和 第一个元素进行交换

得到:

这样就进行了一次交换,将最小的 10 交换到了第一个元素。

继续开始第二轮比较:

判断 14 < 37 ,min = 14

判断 14 < 42 , min 保持不变

判断 14 < 28,min保持不变

判断 14 < 28 , min保持不变

那么 14 就是剩余元素中最小的值

继续第三轮:

判断 37 < 42 , min = 37

判断 37 < 28 , 改变min的值,min = 28

判断 28 = 28 ,min的值可以保持不变

那么将 元素进行交换:

得到:

继续第四轮:

判断 42 < 37 ,min = 37

判断 37 < 28 ,min = 28

然后将剩余元素的第一个元素和最小的元素进行交换

得到:

继续第五轮:

判断 37 < 42 ,那么 min = 37

那么 37 的位置保持不变

继续最后一轮:

只剩下一个元素 42 了,那么 min = 42

这样所有的元素都排序完毕,数组也是从小到大的排列。

5. 代码实现

现在来看看具体的代码:

 public static void select_sort(int[] data) {
    int length = data.length;
    int min = 0;
    for(int i = 0; i < length - 1; i++) {
       min = i;
       for(int j = i + 1; j < length; j++) {
         if(less(data[j], data[min])) min = j;
       }
       exch(data, i, min);
    }
 }
 
 public static boolean less(int a, int b){
     return a < b;
 }
 public static void exch(int[] a, int i, int j) {
     int temp = a[i];
     a[i] = a[j];
     a[j] = temp;
 }

外循环 是将 剩余未排序元素的第一个元素设置为 最小元素

内循环 是找出剩余未排序元素中最小元素的位置

然后将他们交换位置。

6. 时间复杂度

即便 是一个有序的数组进行选择排序,他的比较次数依旧是 n(n -1)/2 次

那么它的时间复杂度是 O( n^2 )。