八大排序选择排序
一、选择排序是什么?
选择排序(Selection Sort)是一种简单直观的排序算法,其核心思想是每次从未排序区间中选出最小(或最大)的元素,将其放到已排序区间的末尾。通过不断缩小未排序区间的范围,最终完成整个数组的排序。
时间复杂度:O(n²)(无论数据是否有序)
空间复杂度:O(1)(原地排序)
稳定性:不稳定排序(可能改变相同元素的相对顺序)
二、选择排序的核心步骤
- 初始化未排序区间
整个数组初始为未排序区间。 - 寻找最小值
遍历未排序区间,找到最小元素的下标。 - 交换元素位置
将最小元素与未排序区间的第一个元素交换。 - 缩小未排序区间
重复上述步骤,直到所有元素有序。
三、选择排序的Java实现
import java.util.Arrays;
public class SelectionSort {
public static void main(String[] args) {
int[] arr = {33, 4, 76, 48, 33, 2, 3, 6, 4};
selectionSort(arr);
System.out.println("排序结果: " + Arrays.toString(arr));
}
public static void selectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i; // 记录最小值的索引
// 遍历未排序区间寻找最小值
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 交换元素
if (minIndex != i) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
代码解析
- 外层循环:控制未排序区间的起始位置
- 内层循环:寻找未排序区间中的最小值索引
- 元素交换:将最小值交换到已排序区间的末尾
四、示例演示(数组[5,3,8,6,2])
轮次 | 未排序区间 | 最小值 | 交换结果 |
---|---|---|---|
1 | [5,3,8,6,2] | 2 | [2,3,8,6,5] |
2 | [3,8,6,5] | 3 | [2,3,8,6,5] |
3 | [8,6,5] | 5 | [2,3,5,6,8] |
4 | [6,8] | 6 | [2,3,5,6,8] |
五、复杂度分析
指标 | 说明 |
---|---|
时间复杂度 | O(n²)(需进行n(n-1)/2次比较) |
空间复杂度 | O(1) |
稳定性 | 不稳定(交换可能破坏相对顺序) |
六、优缺点对比
优点 | 缺点 |
---|---|
实现简单,代码易读 | 时间复杂度高,效率低 |
原地排序,内存占用少 | 不适合大规模数据排序 |
交换次数少(最多n-1次) | 不稳定 |
七、优化策略
-
同时寻找最小和最大值
每轮遍历同时找到最小和最大值,减少遍历次数:for (int i = 0; i < arr.length / 2; i++) { int minIndex = i, maxIndex = i; for (int j = i; j < arr.length - i; j++) { if (arr[j] < arr[minIndex]) minIndex = j; if (arr[j] > arr[maxIndex]) maxIndex = j; } // 交换最小值和左边界 swap(arr, i, minIndex); // 处理最大值在左边界的情况 if (maxIndex == i) maxIndex = minIndex; // 交换最大值和右边界 swap(arr, arr.length - 1 - i, maxIndex); }
-
链表优化
对于链表结构,选择排序无需移动元素,只需修改指针,时间复杂度仍为O(n²)但性能优于数组。
八、应用场景
- 小规模数据排序(如n < 1000)
- 对内存使用有严格限制的环境
- 需要减少交换次数的场景(如SSD寿命敏感场景)
为什么选择排序不稳定?
示例:数组[5, 3, 5, 2]
,第一轮交换后第一个5与2交换,导致两个5的相对顺序改变。
选择排序和冒泡排序的区别?
- 交换次数:选择排序每轮最多交换1次,冒泡排序可能多次交换
- 稳定性:冒泡排序稳定,选择排序不稳定
- 效率:选择排序通常优于冒泡排序
十、总结
选择排序以其简单性和低交换次数的特点,在小规模数据排序中仍有一定应用价值。尽管其时间复杂度较高,但理解其“选择-交换”的核心思想,是学习更复杂排序算法(如堆排序)的基础。在实际开发中,需根据数据规模、稳定性要求等因素综合选择排序策略。