选择排序
彪哥的性格就是先看代码,代码如下:
public class SelectionSort {
public static void main(String[] args) {
int [] arr = {5,2,9,7,3,1,4,6,8,0};
//排序前
for(int i:arr){
System.out.print(i+" ");
}
System.out.println();
int out,in,min;
for(out=0;out<(arr.length-1);out++){
min = out;
for(in=out+1;in<arr.length;in++){
if(arr[in] < arr[min]){
min = in;
}
}
//交换min out值
int tmp = arr[out];
arr[out] = arr[min];
arr[min] = tmp;
}
//排序后
for(int i:arr){
System.out.print(i+" ");
}
}
}
5 2 9 7 3 1 4 6 8 0
0 1 2 3 4 5 6 7 8 9
外层循环用循环变量out,从数组开头开始(数组下标为0)向高位增长。内层循环用循环变量in,从out所指位置开始,同样是向右移位。
min开始也指向最左端,在每一个in的新位置,数据项a[in]和a[min]进行比较。如果a[in]更小,则min被赋值为in的值。在内层循环的最后,min指向最小的数据项,然后交换out和min指向的数组数据项。
详细解释:
箭头outer从左边开始,指向最左边的未排序的竖条。渐渐地,随着越来越多的竖条加入到左端已有序的竖条队列中,箭头outer不断地右移。
箭头min开始也指向最左端的竖条,它会移到当前找到的最短的竖条上。
箭头inner标记当前正在和最小值比较的竖条
inner从左向右移动,依次检查每一个竖条,并且和min所指的竖条进行比较。如果inner所指的竖条更短,min则指向这个新的更短的竖条。当inner到达最右端时,min就指向了未排序的最短的竖条。于是这个竖条和outer所指的竖条,即最左边的无序竖条交换位置。
outer左边的竖条都是有序的,箭头inner从outer所指的位置向右进行扫描,寻找最短的竖条。箭头min记录了这个竖条的位置,它将和outer所指的竖条交换位置。
选择排序的效率
选择排序改进了冒泡排序,将必要的 交换次数 从O(N2) 减少到O(N)。不幸的是比较次数仍保持为O(N2)。 选择排序和冒泡排序执行了相同次数的比较:N*(N-1)/2。对于10个数据项,需要45次比较。然而,10个数据项只需要少于10次交换。对于100个数据项,需要4950次比较,但只进行了不到
100次的交换。 N值很大时,比较的次数是主要的,所以结论是选择排序和冒泡排序一样运行了O(N2)时间。但是,选择排序无疑更快,因为它进行的交换少得多。当N值较小时,特别是如果交换的时间级比比较的时间级大得多时,选择排序实际上是相当快的。