选择排序
1. 算法思想
首先在未排序序列中找到最小元素,存放在未排序序列中的第一位
再从剩余未排序元素中继续寻找最小元素,然后放到在未排序序列中的第一位
以此类推,直到所有元素均排序完毕
2. 特点
- 运行时间和输入的数组是没有关系的
比如说 一个有序的数组 和 一个无序的数组所用的时间其实是一样的
- 数据移动是最少的
因为每次交换都会改变两个数组元素的值,所以选择排序是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 )。