排序方法
- 找到最小的元素
- 放到已排序序列的末尾
分析
时间复杂度:
- 最好:O(n^2),顺序情况
- 最坏:O(n^2),逆序情况
空间复杂度:
- O(1)
不稳定排序
原定排序
代码
public static int[] selectionSort(int[] nums) {
if (nums == null || nums.length < 2) {
return nums;
}
for (int i = 0; i < nums.length; i++) {
// 已排序序列末尾位置
int smallestIndex = i;
for (int j = i; j < nums.length; j++) {
if (nums[j] < nums[smallestIndex]) {
smallestIndex = j;
}
}
int temp = nums[smallestIndex];
nums[smallestIndex] = nums[i];
nums[i] = temp;
}
return nums;
}
优化代码
- 二元选择排序,每轮选择时记录最小值和最大值,可以把数组需要遍历的范围缩小一倍。
public static void selectionSort2(int[] arr) {
int minIndex, maxIndex;
// i 只需要遍历一半
for (int i = 0; i < arr.length / 2; i++) {
minIndex = i;
maxIndex = i;
for (int j = i + 1; j < arr.length - i; j++) {
if (arr[minIndex] > arr[j]) {
// 记录最小值的下标
minIndex = j;
}
if (arr[maxIndex] < arr[j]) {
// 记录最大值的下标
maxIndex = j;
}
}
// 如果 minIndex 和 maxIndex 都相等,那么他们必定都等于 i,
// 且后面的所有数字都与 arr[i] 相等,此时已经排序完成
if (minIndex == maxIndex) break;
// 将最小元素交换至首位
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
// 如果最大值的下标刚好是 i,由于 arr[i] 和 arr[minIndex] 已经交换了,
// 所以这里要更新 maxIndex 的值。
if (maxIndex == i) maxIndex = minIndex;
// 将最大元素交换至末尾
int lastIndex = arr.length - 1 - i;
temp = arr[lastIndex];
arr[lastIndex] = arr[maxIndex];
arr[maxIndex] = temp;
}
}