升序
解决方案
选择排序核心思想如下:
- 从序列中找到最大的元素,与末尾元素交换。
- 排除已经找到的最大元素,重复步骤1。
private static void sort(Integer[] data) {
//从后面逐步减少遍历个数
for (int end = data.length-1; end > 0; end--) {
//假设0是最大
int maxIndex = 0;
for (int start = 1; start <= end; start++) {
// <=能增加稳定性,但是不能保证稳定性
if (data[maxIndex] <= data[start]) {
maxIndex = start;
}
}
//将找到的最大值与最后个元素交换
swap(data,maxIndex,end);
}
}
测试代码:
public static void main(String[] args) {
//获取随机数
Integer[] array = Integers.random(10, 1, 10);
Integers.println(array);
assert array != null;
Times.test("选择排序", () -> {
sort(array);
});
Integers.println(array);
}
输出:
3_10_6_8_1_4_5_5_6_9
【选择排序】
开始:18:00:35.324
结束:18:00:35.325
耗时:0.0秒
-------------------------------------
1_3_4_5_5_6_6_8_9_10
Process finished with exit code 0
稳定性
- 选择排序由于交换的次数要远远少于冒泡排序的次数,所以性能会高一些。 但是最好最坏的时间复杂度都是O(n*n)
- 实现时需要注意 稳定性--> 选择排序是 不稳定的
如下:
7 5 10 10 2 4 2
使用选择排序,第一次遍历就会将位置3和位置6交换
7 5 10 2 2 4 10
此时两个2的原有顺序被打乱,已经不稳定了。
同理 堆排序也是不稳定的。
优化
选择排序主要的时间消耗是在于 选最值。我们可以通过缩短这个时间来进行优化。
使用堆来选最值 时间复杂度就是logn,整个排序时间复杂度就是nlogn
参考:小码哥的恋上数据结构第二期