〇、前言
<<数据结构与算法系列之总篇>>
一、排序算法
下面常用排序算法的动图都是从网络挑选的好理解的动图。
01、冒泡排序
02、选择排序
03、插入排序
04、希尔排序
05、快速排序
06、归并排序
07、堆排序
08、计数排序
09、桶排序
10、基数排序
二、Java排序
1、DualPivotQuicksort.sort
根据数组的元素个数、nearly sorted和元素类型等来选择具体排序算法。例如对整数排序:
if (元素个数 < 47) {
插入排序
return;
}
if (元素个数 < 286) {
双轴快排
return;
}
// 判断数组是否是nearly sorted:统计数组中有序段的个数(包括正序和逆序),
// 如果有序段的个数 < 67,那么说明数组是nearly sorted,使用归并排序,归并所有有序段;
// 否则,说明数组不是nearly sorted,使用双轴快排
if (nearly sorted) {
归并排序
} else {
双轴快排
}
2、Arrays.legacyMergeSort
一个遗留个归并排序算法,未来的版本中将会淘汰,这里不予探究。
3、Timsort.sort | ComparableTimSort.sort
二分插入,一种优化的插入排序:标准插入排序是循环遍历查找元素的插入位置,而二分插入则是通过二分查找来找到元素的插入位置。
Timsort简单来说就是,分段 -> 利用插入排序(通过头部有序序列和二分插入优化)使其有序 -> 将有序段归并 -> 完成排序
4、为何Java不使用堆做纯排序
- 从cpu缓存的角度,堆是跳跃操作数组的,无法利用cpu缓存预读;
- 从nearly sorted角度,如果一个数组很多部分都是有序的,使用堆排序,会将其先打散,反而效率不如快速排序和归并排序;
- 堆是用数组实现的,要求内存连续,数据量大的时候不合适;
三、总结
JDK提供的排序算法很好,根据自己特定场景选择用JDK的还是自己实现。