选择排序,将一个序列看做两个部分,前面有序,后面无序,每次在后面的无序序列中,选择一个最小的元素,交换到前面有序序列的末尾,直到无序序列全部完成交换,即可完成排序
选择排序是不稳定的排序算法
如何判断一个排序算法是否稳定
- 如果一个待排序列中有多个相同的元素,经过排序后,它们的次序保持不变,则称这种排序算法是稳定的
- (即假如有元素A = 5,B = 5,且 A 在 B 的前面,经过排序后,A 还在 B 的前面,则称这种排序算法是稳定的)
基本思想:
- 第一次:从待排序的序列中选出最小的一个元素,存放在序列的起始位置
- 第二次:再从剩余的未排序元素中寻找到最小元素,放到已排序的序列的末尾
- 以此类推,直到全部待排序的数据元素的个数为零。
举例分析:
有一个序列(5, 2, 0, 1, 3, 1, 4)
第一趟排序:
- 先选择 5 为最小的元素 min = 5
- 然后将它后面元素依次和最小元素min进行比较
- 2比 min 小,令 min = 2
- 0比 min 小,令 min = 0
- 1比 min 大,不处理
- 3比 min 大,不处理
- 1比 min 大,不处理
- 4比 min 大,不处理
- 此时的最小元素为 min = 0
- 所以将它和 5 进行交换(0, 2, 5, 1, 3, 1, 4)
第二趟排序:
- 先选择 2 为最小的元素 min = 2
- 然后将它后面元素依次和最小元素min进行比较
- 5比 min 大,不处理
- 1比 min 小,令 min = 1
- 3比 min 大,不处理
- 1不比 min 小,不处理
- 4比 min 大,不处理
- 此时最小元素 min = 1
- 所以将它和 2 进行交换(0, 1, 5, 2, 3, 1, 4)
此时我们看到,经过两趟排序,前面两个元素 0, 1 已经是有序的了
所以我们只需重复执行上面的操作,直到后面元素都比较完为止,即可完成排序
总的来说,就是每次在后面的无序序列中,选择一个最小的元素,交换到前面有序序列的末尾,直到无序序列全部完成交换
动图演示
Java代码
package algorithm;
public class Sort {
// 选择排序算法
public static void selectSort(int[] array) {
for (int i = 0 ; i < array.length - 1 ; i++) {
// 先令最小的元素的下标 等于 当前元素的下标
int minIndex = i;
// 然后寻找比当前元素还小的元素的下标
for (int j = i ; j < array.length ; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
// 找到之后,进行交换
// 如果没找到,则当前就是最小的,不用交换
if (minIndex != i) {
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
}
public static void main(String[] args) {
int[] array = new int[]{5, 2, 0, 1, 3, 1, 4};
Sort.selectSort(array);
// 打印数组
for (int i = 0 ; i < array.length ; i++) {
System.out.print(array[i] + " ");
}
}
}
时间复杂度
- 最好情况:O(n²),序列有序,无需进行交换,但仍需全部进行比较
- 平均情况:O(n²)
- 最坏情况:O(n²),序列逆序,需要全部进行比较,然后进行交换