排序算法-选择排序
方法
假设数组有n个无序元素。
首先在 [ 0, length-1 ] 中找到最小的元素,并将该元素与数组第 0 位进行交换。
然后在 [ 1, length-1 ] 中找到最小的元素,并将该元素与数组第 1 位进行交换。
…
然后在 [ i, length-1 ] 中找到最小的元素,并将该元素与数组第 i 位进行交换。
…
最后在 [ length-1, length-1 ] 中找到最小的元素,并将该元素与数组第 length-1 位进行交换。
实现
@Override
public void sort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int minLoc = i;
for (int j = i; j < arr.length; j++) {
if (arr[minLoc] > arr[j])
minLoc = j;
}
// swap
int temp = arr[minLoc];
arr[minLoc] = arr[i];
arr[i] = temp;
}
}
复杂度分析
选择排序有两个特点:
- 时间复杂度不受数组初始状态影响。因为不管是什么情况,每次交换前都会对数组进行扫描并找出最小值,并且这个扫描次数只会受扫描区间长度影响。因此在时间复杂度上,最好情况,平均情况和最差情况都是一样的。
- 数据移动和数组大小是线性关系。下面的分析可以知道,该算法只需要进行 n 次交换。
时间复杂度
扫描
找到最小值需要对数组进行扫描。
第 1 次扫描区间 [ 0, length-1 ],需要 n 次。
第 2 次扫描区间 [ 1, length-1 ],需要 n-1 次。
…
第 i 次扫描区间 [ i-1, length-1 ],需要 n-i+1 次。
…
第 n 次扫描区间 [ length-1, length-1 ],需要 1 次。
一共是 1+2+3…+n = (n^2+n)/2 次
交换
每次扫描完一个区间,都会将该区间最小值和该区间第一个元素进行交换,一共扫描 n 次,也就是交换了 n 次。
总时间
得出总共需要 大约 (n^2)/2 次扫描和 n 次交换。
因此,时间复杂度为 O(n^2)。
空间复杂度
所需要的辅助存储空间只有扫描时临时存放的最小值,所以空间复杂度为 O(1)。