前幾天整理的一套面試題,其中有一個問題就是Java的JDK中咱們見到的Collections.sort()和Arrays.sort()這兩個排序算法的實現方式是什麼,不少小夥伴內心邊默認的應該是快排,可是不全對或者理解的不夠深入,如下咱們從源碼的層次一點點解釋一下這個問題:面試
先來看看Arrays.sort(),sort方法擁有不少的重載,有十幾種,以int查看以下:算法
public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); }
能夠看到這裏有一個DualPivotQuicksort,DualPivotQuicksort翻譯過來就是雙軸快速排序(關於雙軸快速排序咱們後期在討論,能夠認爲是對咱們普通使用的快排的一種改進,另外還有一種改進是三路快排!),再次點進去,能夠發現有這麼一段代碼:數組
if (right - left < QUICKSORT_THRESHOLD) { sort(a, left, right, true); return; }
發現若是數組的長度小於QUICKSORT_THRESHOLD的話就會使用這個雙軸快速排序,而這個值是286。ui
那若是大於286呢,它就會判斷數組的連續升序和連續降序性好很差,若是好的話就用歸併排序,很差的話就用快速排序,看下面這段註釋就能夠看出:spa
/* * The array is not highly structured, * use Quicksort instead of merge sort. */
那如今再回到上面的決定用雙軸快速排序的方法上,再點進去,發現又會多一條判斷:翻譯
// Use insertion sort on tiny arrays if (length < INSERTION_SORT_THRESHOLD) { //。。。。 }
即若是數組長度小於INSERTION_SORT_THRESHOLD(值爲47)的話,那麼就會用插入排序了,否則再用雙軸快速排序!code
總結,若是數組長度大於等於286且連續性好的話,就用歸併排序,若是大於等於286且連續性很差的話就用雙軸快速排序。若是長度小於286且大於等於47的話就用雙軸快速排序,若是長度小於47的話就用插入排序。示意圖以下:
blog
再來看看Collections.sort(),一步步點進去,發現會進到Arrays裏:
會發現若是LegacyMergeSort.userRequested爲true的話就會使用歸併排序,能夠經過下面代碼設置爲true:
不過方法legacyMergeSort的註釋上有這麼一句話,說明之後傳統歸併可能會被移除了。
若是不爲true的話就會用一個叫TimSort的排序算法,這個算法有興趣的能夠了解一下!排序