天天看點

java 快排_Java提供的排序算法是怎麼實作的?快排?

作者:Java後端技術來源:https://blog.csdn.net/bntx2jsqfehy7/article/details/79707121
           

前幾天整理的一套面試題,其中有一個問題就是Java的JDK中我們見到的Collections.sort()和Arrays.sort()這兩個排序算法的實作方式是什麼,很多小夥伴心裡邊預設的應該是快排,但是不全對或者了解的不夠深刻,以下我們從源碼的層次一點點解釋一下這個問題:

一、Arrays.sort()的排序算法

先來看看Arrays.sort(),sort方法擁有很多的重載,有十幾種,以int檢視如下:

java 快排_Java提供的排序算法是怎麼實作的?快排?

可以看到這裡有一個DualPivotQuicksort,DualPivotQuicksort翻譯過來就是雙軸快速排序(關于雙軸快速排序我們後期在讨論,可以認為是對我們普通使用的快排的一種改進,另外還有一種改進是三路快排!),再次點進去,可以發現有這麼一段代碼:

java 快排_Java提供的排序算法是怎麼實作的?快排?

發現如果數組的長度小于QUICKSORT_THRESHOLD的話就會使用這個雙軸快速排序,而這個值是286。

那如果大于286呢,它就會判斷數組的連續升序和連續降序性好不好,如果好的話就用歸并排序,不好的話就用快速排序,看下面這段注釋就可以看出

java 快排_Java提供的排序算法是怎麼實作的?快排?

那現在再回到上面的決定用雙軸快速排序的方法上,再點進去,發現又會多一條判斷:

java 快排_Java提供的排序算法是怎麼實作的?快排?

即如果數組長度小于INSERTION_SORT_THRESHOLD(值為47)的話,那麼就會用插入排序了,不然再用雙軸快速排序!

總結,如果數組長度大于等于286且連續性好的話,就用歸并排序,如果大于等于286且連續性不好的話就用雙軸快速排序。如果長度小于286且大于等于47的話就用雙軸快速排序,如果長度小于47的話就用插入排序。示意圖如下:

java 快排_Java提供的排序算法是怎麼實作的?快排?

二、Collections.sort()的排序算法

再來看看Collections.sort(),一步步點進去,發現會進到Arrays裡:

java 快排_Java提供的排序算法是怎麼實作的?快排?

會發現如果LegacyMergeSort.userRequested為true的話就會使用歸并排序,可以通過下面代碼設定為true:

java 快排_Java提供的排序算法是怎麼實作的?快排?

不過方法legacyMergeSort的注釋上有這麼一句話,說明以後傳統歸并可能會被移除了。

java 快排_Java提供的排序算法是怎麼實作的?快排?

如果不為true的話就會用一個叫TimSort的排序算法,這個算法有興趣的可以了解一下!

三、總結

在面試的時候如何秒殺衆人,當問到這個問題的時候,我們就不要再脫口而出隻是快排而已了!

繼續閱讀