1、算法描述
选择排序的关键是把整个数组,分为两个部分,一部分是已排序部分,另一部分是未排序部分,当然一开始所有元素处于一个未排序部分中,我们从每一轮排序中找到一个最小值的元素然后把它交换到已排序的部分中,然后不断重复这个过程,每轮都找到最小值交换到已排序部分中,不断重复这个过程,最后可以让整个数组有序。
这里有一个无序数组,那我们要从这个未排序的部分中挑出一个最小的元素 。
先假定3是最小的元素,然后把它跟后面的元素去比较。
跟2比,2比3小,然后重新选择2是最小的元素。
然后再把这个最小的值和后续的值进行比较。
比较完一轮,已经找出最小值1。那我们把1放到已排序部分,索引0的位置作为已排序的位置,把1交换过去。
然后再把这个最小的值和后续的值进行比较。
这样这个1就处于已排序的部分。剩下蓝色的部分就处于未排序的部分,这就完成了一轮选择。
然后就重复以上操作,一直到数组有序为止。
小结:
将数组分为两个子集,排序的和未排序的,每一轮从未排序的子集中选出最小的元素,放入排序子集。
重复以上步骤,直到整个数组有序。
2、算法实现
package com.zking.select;
import java.util.Arrays;
/**
* @description:选择排序Demo
* @author: jie
* @time: 2022/2/21 18:59
*/
public class SelectionSort {
public static void main(String[] args) {
int[] a = {5, 3, 7, 2, 1, 9, 8, 4, 6};
selection(a);
}
private static void selection(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
// i代表每轮选择最小元素要交换到的目标索引
//s代表最小元素的索引值
int s = i;
for (int j = s + 1; j < a.length; j++) {
//如果j的值更小就把j的值赋值给s
if (a[s] > a[j]) {
s = j;
}
}
//如果 s==i 就说明当前i已经是最小值了,不需要交换
if (s != i) {
swap(a, s, i);
}
System.out.println(Arrays.toString(a));
}
}
/**
* @description:排序方法
* @author: jie
* @time: 2022/2/21 19:15
*/
public static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
3、与冒泡排序比较
-
二者平均时间复杂度都是 $O(n^2)$,都是比较慢的。
-
选择排序一般要快于冒泡,因为其交换次数少。
-
但如果集合有序度高,冒泡优于选择。
-
冒泡属于稳定排序算法,而选择属于不稳定排序。
-
稳定排序指,按对象中不同字段进行多次排序,不会打乱同值元素的顺序
-
不稳定排序则反之。
-