假设你的计算机存储了很多音乐,对于每首音乐,你都记录了其播放次数。
那么你需要将这个音乐列表按播放次数从多到少进行排序。假设这个列表的长度是 n
首先遍历这个列表,找出播放次数最多的歌曲,将其放到一个新列表的第一位,操作遍历 次数为 n
然后再次编译剩下的列表,找出播放次数最多的歌曲,把它放到排序列表的第二位,操作遍历 次数 为 n-1
以此类推操作遍历次数为 n-2;...2;1
这样最终得到一个有序列表,这就是选择排序。选择排序是一种灵巧的算法,但是速度不快。
选择排序的最终操作次数为(n+n-1...+2+1),也就是 n 的递减的和,运行效率书上是记做 O(n2),其实是O((n2-n)/2)
那么n+n的递减的和为:(n2+n)/2
/**
* java选择排序
* @param arr 数组
*/
public void selectionSort(Comparable[] arr){
int N= arr.length; //数组长度
int count=0; // 统计排序次数
for (int i = 0; i < N; i++) {
int min =i;
//这里纠正下网上一些同学 int j = i; j < N; j++ 的写法,既然 已经 min=i,那么i 就不用跟他自己比较了,直接比较后面一个
for (int j = i+1; j < N; j++){
count++;
if (arr[j].compareTo(arr[min])<0) { //判断判断当前数值是否小于最小值
min = j;
}
}
//交互数组顺序,思路是每一次找到最小的,然后放到 i 的位置(第一次是最小的,第二次是第二小的)
Comparable c =arr[i];
arr[i] =arr[min];
arr[min] =c;
}
}
有人认为选择排序比 冒泡排序要快,是真的嘛?
/**
* 冒泡排序
* @param arr
*/
public void maoPaoSort(Integer[] arr){
int counts=0;//冒泡排序次数
for(int i=0;i<arr.length-1;i++){ //外层循环 n-1 ,控制比较轮数
for(int j=0;j<arr.length-1-i;j++){ //内层循环 n-1-i ,控制每一轮比较次数
counts++;
if(arr[j]>arr[j+1]){ //两两比较做交换 ,判断大小交换位置
int number=arr[j];
arr[j]=arr[j+1];
arr[j+1]=number;
}
}
}
}
测试结果
其实可以看到它们循环比较的次数都是一样的。但是为什么说选择排序比冒泡排序要快呢?
仔细看代码,你会发现选择排序的数组位移在外层循环,而冒泡排序的位移在内循环。
因此选择排序比冒泡排序效率要高