个人浅薄意见,难免有误,还请各位看官批评指正。
选择排序
一、算法思想
选择排序我认为可以这么理解,将要排序的数组分为两个部分,前面是已经排序的元素,后面是未排序的元素序列。第一次遍历之前整个数组是未排序状态,第一次遍历数组,找出数组中最小(最大)的元素与数组第一位交换位置,则[0]为已排序,[1,length-1]为未排序,第二次遍历找出[1,length-1]中最小的元素,与[1]交换,则[0,1]已排序,[2,length-1]未排序,迭代操作即可完成排序。
下面是Java代码实现:
import java.util.Random;
public class SelectSort {
public static void selectSort(Comparable[] a){
for(int i=0;i<a.length;i++){ //每完成一次遍历,则0至i已排序
int min = i; //假设未排序序列第一个元素最小
for(int j=i+1;j<a.length;j++){
if(less(a[j],a[min])){
min = j; //记录当前遍历到的最小元素的位置
}
}
/*
* 此时min指的就是i+1至a.length-1最小元素的位置,将其与a[i]交换位置
* 完成0至i的排序
*/
exchange(a, i, min);
}
}
/**
* 判断元素m是否小于n
* @param m
* @param n
*/
private static boolean less(Comparable m,Comparable n){
return m.compareTo(n)<0;
}
/**
* 交换数组中两个元素
* @param a
* @param m
* @param n
*/
private static void exchange(Comparable[] a,int m,int n){ //注意Java中参数传递机制是值传递(Value transfer)
Comparable temp;
temp = a[m];
a[m] = a[n];
a[n] = temp;
}
public static void main(String[] args) {
Comparable[] a = new Comparable[20];
Random random = new Random();
for(int i=0;i<20;i++){
a[i] = random.nextInt(40+1)-20; //随机生成-20到20范围的数
}
for(Comparable i:a){
System.out.print(i + " ");
}
System.out.println();
selectSort(a);
for(Comparable i:a){
System.out.print(i + " ");
}
}
}
二、效率分析
个人看法:学习算法除了学习算法的思想,其次很重要的一点就是对它的效率进行分析,这是非常重要的,这能够判断你是否已充分的理解了算法。
交换次数:
由代码分析可知,exchange()方法执行的次数为N,故选择排序的交换次数为数组的长度。 注:N为数组长度
比较次数:
外层循环i=0时,内层循环的比较次数为N-1,i=1时,比较次数为N-2......
归纳法即知:比较次数为N(N-1)/2~N^2/2。