原理: 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
举例: 数组array有5个元素{3, 9, -1, 10, -2},从小到大排序
原理分析:本质就是5个元素中找四个最小的往前放,这样最后一个数一定是最大的且位置确定的
第一次循环: 假定第一个元素3是最小的,依次与后面的数进行比较
9比3大,不需要记录
-1比3小,记录下来-1的下标和值,这时候-1是最小的,接着继续当前循环
10比-1大,不需要记录
-2比-1小,记录下来-2的下标和值,这时候-2是最小的,当前循环已经到最后,这时候最小值就是记录下来的-2,让它跟我们假定的第一个元素3交换位置,数组变成{-2, 9, -1, 10, 3},最小的数我们已经找到,接着找第二小的数
第二次循环: 假定第二个元素9是最小的,依次与后面的数进行比较
-1比9小,记录下来-1的下标和值,这时候-1是最小的,接着继续当前循环
10比-1大,不需要记录
3比-1大,不需要记录,当前循环已经到最后,这时候最小值就是记录下来的-1,让它跟我们假定的第二个元素9交换位置,数组变成{-2, -1, 9, 10, 3},第二小的数我们已经找到,接着找第三小的数
第三次循环: 假定第三个元素9是最小的,依次与后面的数进行比较
10比9大,不需要记录
3比9小,记录下来3的下标和值,这时候3是最小的,当前循环已经到最后,这时候最小值就是记录下来的3,让它跟我们假定的第三个元素9交换位置,数组变成{-2, -1, 3, 10, 9},第三小的数我们已经找到,接着找第四小的数
第四次循环: 假定第四个元素10是最小的,依次与后面的数进行比较
9比10小,记录下来9的下标和值,这时候9是最小的,当前循环已经到最后,这时候最小值就是记录下来的9,让它跟我们假定的第四个元素10交换位置,数组变成{-2, -1, 3, 9, 10},第四小的数我们已经找到,五个元素我们找到四个最小的,而且位置都是从小到大,那么第五个元素的位置就是确定的了
图解{3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48}:
代码:
import java.util.Arrays;
/**
* 选择排序
*
* @author codewen
*
*/
public class SelectSort {
// 对数组进行排序的方法
// {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48}
public static void sort(int[] array) {
int minIndex = 0;//用于记录比较时最小数的下标
int min = 0;//用于记录比较时的最小数
for (int i = 0; i < array.length - 1; i++) {
minIndex = i;
min = array[i];
for (int j = i + 1; j < array.length; j++) {
if (array[minIndex] > array[j]) {
minIndex = j;//记录比较时最小数的下标
min = array[j];//最小数
}
}
if (minIndex != i) {// 优化之处,可能我们假定的数就是最小的数,此时不需要交换
array[minIndex] = array[i];
array[i] = min;
}
}
}
public static void main(String[] args) {
int[] array = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
System.out.println("排序前的数组:" + Arrays.toString(array));
sort(array);
System.out.println("排序后的数组:" + Arrays.toString(array));
// 测试8万条数据需要耗费多久
// int[] array = new int[80000];
// for (int i = 0; i < 80000; i++) {
// array[i] = (int) (Math.random() * 80000);
// }
// System.out.println(System.currentTimeMillis());
// sort(array);
// System.out.println(System.currentTimeMillis());
}
}
// 时间复杂度为O(n^2),但是比冒泡排序更快,因为选择排序每次最多只进行一次数据交换,而冒泡排序很明显远远大于一次数据交换
// 如果是8万个数据,平均时间大概在2s左右
结果:
8万条数据大概耗费2s左右,可见选择排序比冒泡排序更高效