1. 程式人生 > >各大排序演算法優缺點總結

各大排序演算法優缺點總結

  我這裡只總結各大演算法知識的要點,如果你想看看演算法思想和實現程式碼,網上的其他部落格都很喜歡貼大段程式碼和文字,可以自己去看。

  (如果出錯,請指正!感激不盡!)

一.三大簡單、慢速排序演算法

平均

最好

最壞

輔助儲存

穩定性

直接插入

n^2

n

n^2

1

穩定

直接選擇

n^2

n^2

n^2

1

不穩定

直接交換(冒泡)

n^2

n

n^2

1

穩定

我省略了O,如:上面的n^2其實是O(n^2)的意思

這三種演算法的有點都是簡單,缺點都是慢。

優點

缺點

直接插入

比較次數越少,移動次數越多

直接選擇

直接交換(冒泡)

每次只移動相鄰兩個元素

二.希爾排序

                 n^1.3         n           n^2         1                不穩定

   希爾排序中,演算法的效率很大程度由增量決定,而一個合適的增量的選擇需要大量的經驗。

三.堆排序

              nlog2n        nlog2n         nlog2n               1          不穩定

        nlog2n的2是下標,在這裡不知道怎麼設定,大家應該瞭解。

    它比快速排序的優點:在最壞情況下它的效能很優越

    它比歸併排序的有點:使用的輔助儲存少

    它的缺點: 不適合太小的待排序列(因為他需要建堆);不穩定,不適合物件的排序

四.快速排序、歸併排序(最常用的排序演算法)

平均

最好

最壞

輔助儲存

穩定性

快速排序

nlog2n

nlog2n

n^2

1

不穩定

歸併排序

nlog2n

nlog2n

nlog2n

n

穩定

       (分治法思想)

PS:二者各自的特點。

         快速排序最快的排序演算法,缺點是不穩定,不適合物件排序;

         歸併排序第二塊的演算法,缺點是輔存很大,適合物件排序;

PS:快速排序遞迴堆疊空間的佔用:

        最優的情況下空間複雜度為:O(logn)  ;每一次都平分陣列的情況

    最差的情況下空間複雜度為:O(n );退化為氣泡排序的情況

PS:一個排整數的測試:

         在筆記本上跑的,對1024*1024個隨機整數排序,快速排序比合並排序快3到4倍。

         [05.0813:40:22] INFO: Performance Check: Quick Sort 1048576 Elements., took 94 ms

         [05.0813:40:22] INFO: Performance Check: Merge Sort 1048576 Elements., took 437 ms

五.以Java 集合類的sort()排序為例子(jdk不同版本sort()實現也不同)

   1.JDK6中的排序是基於傳統的歸併排序做了部分優化,這兩個優化都很簡單,實際上效率並未提高多少。所以在JDK7中將其替換為TimSort。

   2.JDK 7中,內部實現換成了TimSort,其對物件間比較的實現要求更加嚴格,

         (1)傳入的待排序陣列若小於閾值MIN_MERGE(Java實現中為32,Python實現中為64),則呼叫binarySort,這是一個不包含合併操作的 mini-TimSort。二分查詢/折半插入查詢,

從陣列開始處找到一組連線升序或嚴格降序(找到後翻轉)的數。

         (2)否則, 不斷二分,直到小於閾值,然後插入排序;

         TimSort演算法是一種起源於歸併排序和插入排序的混合排序演算法

   3.在jdk8中,如果你看過原始碼就會知道,其實針對不同的情況使用了不同的排序演算法,簡單羅列下:

         (1).如果是簡單物件資料,例如int,double,且陣列長度在一定閥值內,則使用快排,如果在閥值外,則用歸併的變種;

         (2).如果是複雜物件陣列,則如果陣列長度在一定閥值以內,則使用折半插入排序,如果長度在閥值外,則使用歸併法,但是如果歸併二分後小於閥值了,則在內部還是會使用折半插入排序。。。以上只是大概

    大家一定注意到了,閾值以外需要使用歸併,因為快排使用遞迴,如果待排序列太大的話,堆疊可能會溢位;而歸併排序不存在此問題;

    我查閱了jdk8的新功能,其中好像並沒有關於sort()的更新,這樣說來,jdk7和8應該在sort()上沒有區別才對;但是我在知乎上找到了關於jdk8 的sort()描述,好像還有很多人同意的樣子,所以我就把他的言論給貼了過來。

   後來這一塊還是沒弄明白,發了個求助的帖子,有了結果後,我會修改這個博文的。若是有高手看到此處,還望不吝賜教啊!