我在接受採訪時被問到這個問題。 他們都是O(nlogn),但大多數人使用Quicksort而不是Mergesort。 這是爲何? html
在全部條件相同的狀況下,我但願大多數人都能使用最方便的東西,並且每每是qsort(3)。 除了快速排序以外,已知數組上的快速排序很是快,就像mergesort是列表的常見選擇同樣。 java
我想知道爲何看到基數或桶排序這麼罕見。 它們是O(n),至少在鏈表上,所須要的只是將密鑰轉換爲序數的一些方法。 (字符串和浮點數工做正常。) 算法
我認爲緣由與計算機科學的教學方式有關。 我甚至不得不向算法分析的講師證實,確實能夠比O(n log(n))更快地排序。 (他有證據證實你不能比O(n log(n))更快地進行比較 ,這是真的。) 數組
在其餘新聞中,浮點數能夠按整數排序,但您必須在以後轉換負數。 函數
編輯:實際上,這是一種更加惡毒的方式來整理浮點數 - 整數: http : //www.stereopsis.com/radix.html 。 請注意,不管您實際使用哪一種排序算法,均可以使用位翻轉技巧... 性能
對於原始值的DualPivotQuickSort帶來的變化,答案會略微傾向於快速排序。 它在JAVA 7中用於在java.util.Arrays中進行排序 ui
It is proved that for the Dual-Pivot Quicksort the average number of comparisons is 2*n*ln(n), the average number of swaps is 0.8*n*ln(n), whereas classical Quicksort algorithm has 2*n*ln(n) and 1*n*ln(n) respectively. Full mathematical proof see in attached proof.txt and proof_add.txt files. Theoretical results are also confirmed by experimental counting of the operations.
你能夠在這裏找到JAVA7的實現 - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/Arrays.java spa
關於DualPivotQuickSort的更多精彩閱讀 - http://permalink.gmane.org/gmane.comp.java.openjdk.core-libs.devel/2628 code
「然而大多數人使用Quicksort而不是Mergesort。爲何會這樣?」 視頻
沒有給出的一個心理緣由就是Quicksort更加巧妙地命名。 即良好的營銷。
是的,具備三重分區的Quicksort多是最好的通用排序算法之一,可是沒有克服「快速」排序聽起來比「合併」排序更強大的事實。
快速排序是最壞狀況O(n ^ 2),可是,平均狀況始終執行合併排序。 每一個算法都是O(nlogn),但你須要記住,在談論Big O時,咱們忽略了較低的複雜因素。 當涉及常數因素時,快速排序比合並排序有顯着改進。
合併排序還須要O(2n)內存,而快速排序能夠就地完成(只須要O(n))。 這是快速排序一般優於合併排序的另外一個緣由。
額外信息:
當樞軸選擇不當時,會發生最快的快速排序。 請考慮如下示例:
[5,4,3,2,1]
若是選擇樞軸做爲組中的最小或最大數字,則快速排序將在O(n ^ 2)中運行。 選擇列表中最大或最小25%的元素的機率爲0.5。 這使得算法成爲一個良好的支點。 若是咱們採用典型的樞軸選擇算法(好比選擇一個隨機元素),咱們就有0.5個機會爲每一個樞軸選擇一個好的樞軸。 對於大尺寸的集合,老是選擇不良樞軸的機率是0.5 * n。 基於此機率,快速排序對於平均(和典型)狀況是有效的。
爲何Quicksort好?
Quicksort老是比Mergesort好嗎?
並非的。
注意:在java中,Arrays.sort()函數使用Quicksort做爲基本數據類型,使用Mergesort做爲對象數據類型。 由於對象消耗了內存開銷,因此爲Mergesort添加一點開銷可能不是性能觀點的任何問題。
參考 :觀看Coursera的第3周,普林斯頓算法課程的QuickSort視頻