算法:
首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。然后,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置,如此往复,直到整个数组排序。
对于长度为的数组,选择排序需要大约
/2次比较和
次交换。
选择排序有两个特点:
1、运行时间和输入无关。一个有序数组或者主键全部相同的数组和一个元素随机排列的数组所用的排序时间相同。其他算法会更善于利用输入的初始状态。
2、数据移动是最少的。每次交换都会改变俩个数组元素的值,所以选择排序用了N次交换——交换次数和数组的大小是现行关系。而他大部分算法的增长量级都是线性对数或是平方级别。
代码实现:
public class Selection {
// 比较元素大小
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// 将元素交换位置
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i]; a[i] = a[j]; a[j] = t;
}
// 在单行中打印数组
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
// 测试数组元素是否有序
public static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
if (less(a[i], a[i-1])) return false;
}
return true;
}
// 选择排序
public static void sort(Comparable[] a) {
// 将a[] 按升序排列
int N = a.length;
for (int i = 0; i < N; i++) {
// 将a[i] 和a[i+1...N] 中最小的元素交换
int min = i; //最小元素索引
for (int j = i + 1; j < N; j++) {
if (less(a[j], a[min]))
min = j;
exch(a, i, min);
}
}
}
public static void main(String[] args) {
// 读取字符串,将他们排序输出
Comparable[] a = StdIn.readAllStrings();
sort(a);
assert isSorted(a);
show(a);
}
}
结果:
排序前:S O R T E X A M P L E
排序后:A E E L M O P R S T X