简介
选择排序(Selection Sort),它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
文章中使用的动画网站地址,限 pc: 排序算法动画
http://www.donghuasuanfa.com/sort
代码示例
public static void selectSort(int [] arr,int n){
for (int i = 0; i < n - 1; i++) {
int index = i;
int j;
// 找出最小值得元素下标
for (j = i + 1; j < n; j++) {
if (arr[j] < arr[index]) {
index = j;
}
}
int tmp = arr[index];
arr[index] = arr[i];
arr[i] = tmp;
System.out.println(Arrays.toString(arr));
}
}
排序过程
时间复杂度
最差时间复杂度 | 平均时间复杂度 | 最优时间复杂度 |
---|---|---|
O ( N 2 ) O(N^2) O(N2) | O ( N 2 ) O(N^2) O(N2) | O ( N ) O(N) O(N) |
最差时间复杂度&平均时间复杂度
每轮比较的过程是选择一个元素,然后和未排序数组进行逐个比较,寻找最小值,此过程的时间复杂度为N。每轮比较后找出最小的一个元素。
然后共比较N轮。所以时间复杂度近似为:
O
(
N
2
)
O(N^2)
O(N2)
最优时间复杂度
算法优化。当外层循环时,判断相邻元素的大小,如果元素大小顺序为已排序顺序,一次循环后可结束排序方法。此时的时间复杂度为 O ( N ) O(N) O(N)
代码示例
public static void selectSort(int [] arr,int n){
for (int i = 0; i < n - 1; i++) {
boolean alreadySort = true;
int index = i;
int j;
// 找出最小值得元素下标
for (j = i + 1; j < n; j++) {
if (arr[j] < arr[index]) {
index = j;
alreadySort = false;
}
if(arr[j-1]> arr[j] ){
alreadySort = false ;
}
}
//当前数组没有进行位置,说明为已经排序数组,则结束此循环。
if (alreadySort){
break;
System.out.println(Arrays.toString(arr));
}
int tmp = arr[index];
arr[index] = arr[i];
arr[i] = tmp;
System.out.println(Arrays.toString(arr));
}
}
说明:首先设置已排序数组变量 alreadySort =true。第二层循环内部加判断逻辑,相邻元素进行比较,如果大小位置顺序不正确,则将 alreadySort设置为false。 然后第一层循环内逻辑判断数组是否已排序,如果已排序,则直接结束排序方法。所以时间复杂度为 O(N)。
动画示例
空间复杂度
**空间复杂度: O(1) **
选择排序为交换排序,当两个元素大小不相同时,俩个元素交换位置,无需额外空间,所以空间复杂度为 O(1)。
稳定性
不稳定排序
两个元素的值相同时如果最终排序完成后位置不变,则为稳定排序,如果位置变更则为不稳定排序。
排序算法中,如果数字相同,则无需变更位置,避免额外的操作。
选择排序如果当前锁定元素比后面一个元素大,而后面较小的那个元素又出现在一个与当前锁定元素相等的元素后面,那么交换后位置顺序将会改变。
例:3,7,3,2。第一趟3和2交换位置,那么原序列中的俩个3的位置则互换。所以为不稳定排序。