选择排序(SelectSort),顾名思义,就是每次遍历的时候,都选择一个最小(大)的数进行排序,直到此数排到相应的位置,结束此数的排序,再选除此数外最小(大)的数进行排序。
排序过程图
排序思想
1.初次遍历数组时,根据依次比较,筛选出当前数组中最小的数。
2.将此数通过交换到数组最前的位置,此数则排序完成。
3.再将除排序好的数以外的数组,再次筛选出最小值。
4.再次将当前最小值通过交换,排到数组的最前。
5.重复上述流程,直到整个数组排序完成。
排序代码
public static void selectSort(int[] arr){
//依次筛选并排序最小值
for (int i = 0; i < arr.length - 1; i++) {
//用min记录当前数组最小值的索引
int min = i;
//遍历数组,筛选出最小值得索引
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]){
min = j;
}
}
//交换最小值和当前数组最前的位置的值
swap(arr, min, i);
//此时当前数组最小值得排序完成
}
}
private static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
代码改进——双向选择排序
在上述的代码,即单向选择排序中,一次遍历数组,只能筛选出一个数进行排序,效率略低,则可以考虑一次遍历筛选出两个数,即可以筛选出最小值和最大值。
改进排序思想
1.在每次遍历数组时,筛选出当前数组中的最小值和最大值。
2.将最小值和最大值分别交换到当前数组的最前和最后。
3.再将除已排序完的数的数组,再次按照上述流程进行排序。
注:
可能会出现max和low重合的情况,即max的值并未变化的情况,则此时min才是max应该指向的位置。
改进排序代码
public static void selectSortOP(int[] arr){
//记录最小值得索引
int low = 0;
//记录最大值的索引
int high = arr.length - 1;
while (low <= high){
//从左边开始遍历
int min = low;
int max= low;
for (int i = low + 1; i <= high; i++) {
//筛选出更小的数
if (arr[i] < arr[min]){
min = i;
}
//筛选出更大的值
if (arr[i] > arr[max]){
max = i;
}
}
//交换数组最左边的值和最小值
swap(arr, min, low);
//max和low重合的情况
if (max == low){
max = min;
}
//交换数组最右边的值和最大值
swap(arr, max, high);
//移动左右指针
++low;
--high;
}
}
private static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
性能分析
时间复杂度 | 空间复杂度 |
---|---|
O(n^2) | O(1) |
数据不敏感 | 数据不敏感 |