〇、前言
<<數據結構與算法系列之總篇>>
一、排序算法
下面常用排序算法的動圖都是從網絡挑選的好理解的動圖。
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的還是自己實現。