小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
前言
这是"优雅系列"的第三篇,让我们一起来手撕选择排序。
算法描述
- 将数组分为两个子集,排序的和未排序的,每一轮从未排序的子集中选出最小的元素,放入排序子集
- 重复以上步骤,直到整个数组有序
算法实现
private static void selection(int[] a){
for (int i = 0; i < a.length - 1; i++) {
int smallIndex = i;
for(int j = smallIndex + 1;j < a.length;j ++) {
if(a[smallIndex] > a[j]){
smallIndex = j;
}
}
if(i != smallIndex) {
swap(a, i, smallIndex);
}
}
}
private static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
不得不说,选择排序不难,理解起来也不难,实现起来可能就有一点需要说一下,就是如何表示排序区间和未排序区间,可以看到这里是通过 i 不断向右来增加排序区间,而 j 指向的就是未排序区间,这多一个变量 smallIndex 其实就是指向了未排序中的最小值。
还有一点要注意,不要在内层 for 循环的 if 里面就直接 swap,而是记录索引在一轮选择进行完成之后得到最小的值然后才放入排序区间。
还有就是当 i 和 smallIndex 一样的时候,不需要置换,因为 i 这个位置已经是最小的了。
好了,选择排序就说到这里,接下来我们可以和冒泡排序做一个小小的比较。
在比较之前,先说一个概念,算法稳定性,举个例子,如果有两个一样的数,在排序前后,他们在数组的相对位置没有发生变化,这样的算法我们就说是稳定性算法。
选择排序和冒泡排序比较
- 平均时间复杂度都是 n 的平方
- 选择排序一般要快于冒泡,因为交换次数少
- 如果集合有序度比较高,冒泡优于选择
- 冒泡属于稳定性排序算法,选择属于不稳定排序算法
最后
关于算法的比较,我们可以从几个方面来考虑,时间复杂度,空间复杂度,是不是稳定,数组的初始状态,上面这些点也不用刻意去背,理解了算法也就理解了他们之间的优劣,指望记住这些差别是不行的,后面还有很多算法呢,重点是理解算法的思想。