1. 什么是选择排序
我的理解:从左向右一次推举中数组中的最值,推举的方式是:第一次选择所有元素的最值放到数组左边第一位,第二次再从剩下的元素中选择最值放到第二位,依此类推,直到排出数组的顺序为止
2. 图解,由小到大排序,数组为:3,4,1,5,2
2. show me the code
/**
* 选择排序
*/
public class SelectSort {
public static void main(String[] args) {
int[] num = {3, 4, 1, 5, 2};
selectSort(num);
System.out.println("排序后的结果: " + Arrays.toString(num));
}
public static void selectSort(int[] num) {
int len = num.length;
for (int i = 1; i < len; i++) { // 因为外层就是用来计数的, 我自己习惯从1开始
// int midIdx = 0;
// int min = num[0]; // 这里出问题了: 每次推举的时候min以及minIdx应该从上次推举出的下一个数字开始比较
int midIdx = i - 1;
int min = num[i - 1];
for (int j = i; j < len; j++) { // 这里 j = i 是从当前数字的下一个和当前值进行比较, 当前值为最小值(num[i - 1]为当前值, 即外层循环i - 1索引所对应的的值)
// if (num[j] <= min) { // 这里出问题了. 冒泡排序可以两两比较的原因是每次比较之后有交换, 选择排序没有, 选择排序需要记录只是记录最小值, 所以每次需要和记录的最小值比较
// min = num[j];
// midIdx = j;
// } else {
// min = num[j + 1];
// midIdx = j + 1;
// }
if (num[j] < min) {
min = num[j];
midIdx = j;
}
}
int temp = num[i - 1];
num[i - 1] = min;
num[midIdx] = temp;
System.out.println("第" + i + "趟:" + Arrays.toString(num));
}
}
}
// 测试结果
第1趟:[1, 4, 3, 5, 2]
第2趟:[1, 2, 3, 5, 4]
第3趟:[1, 2, 3, 5, 4]
第4趟:[1, 2, 3, 4, 5]
排序后的结果: [1, 2, 3, 4, 5]
3. 时间复杂度:O(n^2)
4. 和冒泡排序的区别:
- 冒泡排序是相邻元素两两比较之后交换,选择排序是每个元素和最值比较
- 冒泡排序是从右向左依次选出最值,所以内层循环参数的最大值在变化(依次缩小);选择排序是从左向右选出最值,所以内存循环参数的初始值在变化(依次变大)
上面的区别也是我上面代码中出错的原因
5. 选择排序总结
- 第一次选择完最值以后和第一个元素交换
- 交换完之后,从剩下的元素中选择完最值之后,和剩下这些元素中的第一个元素交换
> 如有理解不好的地方,希望各位大佬指教