〇、前言
<<数据结构与算法系列之总篇>>
一、排序算法
下面常用排序算法的动图都是从网络挑选的好理解的动图。
01、冒泡排序
02、选择排序
03、插入排序
04、希尔排序
05、快速排序
06、归并排序
07、堆排序
08、计数排序
09、桶排序
10、基数排序
二、Java排序
1、Arrays.sort()
根据数组的元素个数、nearly sorted(近单调性:单调升序和单调降序)和元素类型等来选在具体排序算法。例如对整数排序:
if (元素个数 < 47) {
插入排序
} else if (元素个数 < 286) {
双轴快排
} else if (nearly sorted) {
归并排序
} else {
双轴快排
}
2、Collections.sort()
其实底层也是归到Arrays.sort()对Object[]数组的排序。如果LegacyMergeSort.userRequested为true的话就会使用归并排序,可以通过代码设置为true(System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
)如果不为true的话就会用一个叫TimSort的排序算法。
Timsort 是一种混合稳定的排序算法,源自合并排序和插入排序,旨在较好地处理真实世界中各种各样的数据。该算法通过查找已经排好序的数据子序列,在此基础上对剩余部分更有效地排序。 该算法通过不断地将特定子序列(称为一个 run )与现有的 run 合并,直到满足某些条件为止来达成的更有效的排序。在JavaSE7中引入。有兴趣的可以去研究一下。
3、为何Java不使用堆做纯排序
- 从cpu缓存的角度,堆是跳跃操作数组的,无法利用cpu缓存预读;
- 从nearly sorted角度,如果一个数组很多部分都是有序的,使用堆排序,会将其先打散,反而效率不如快速排序和归并排序。
三、总结
JDK提供的排序算法很好,根据自己特定场景选择用JDK的还是自己实现。