8種排序演算法比較

2022-05-09 02:42:07 字數 3941 閱讀 6424

8種排序演算法,各演算法名稱見下表或見原始碼。執行程式時,將需要你輸入一數值,以確定對多少隨機數進行排序。然後將會顯示各排序演算法的耗時。並且你可選擇時否進行正序和反序測試。

由於水平有限,可能存在一些錯誤,還請各位多多指點!

通過實驗我們可將結果列入下表。

以下是vc6.0(release)+win2000pro+128mddr+p4(1.6g)

因為在多工作業系統下,系統將進行程序式排程,影響實驗結果。以下是經過稍微修正過的值。如果要取得更準確的值,我們得多次實驗求其平均值。

排序演算法實驗比較(單位:秒)n方法

1k10k

100k

200k

100k

正序逆序

氣泡排序

00.422

44.790

188.462

031.459

氣泡排序2

00.281

30.335

131.771

027.568

快速排序00

0.016

0.047

5.095

7.002

直接選擇排序

00.141

16.878

79.332

16.785

33.242

堆排序0

00.031

0.109

0.031

0.015

直接插入排序

00.047

8.705

57.800

024.865

shell排序00

0.047

0.110

0.015

0.015

歸併排序00

0.031

0.094

0.032

0.032

基數排序00

0.47

0.109

0.047

0.046

演算法與結果聯合分析

氣泡排序:在最優情況下只需要經過n-1次比較即可得出結果,(這個最優情況那就是序列己是正序,從100k的正序結果可以看出結果正是如此),但在最壞情況下,即倒序(或乙個較小值在最後),下沉演算法將需要n(n-1)/2次比較。所以一般情況下,特別是在逆序時,它很不理想。它是對資料有序性非常敏感的排序演算法。

氣泡排序2:它是氣泡排序的改良(一次下沉再一次上浮),最優情況和最壞情況與氣泡排序差不多,但是一般情況下它要好過氣泡排序,它一次下沉,再一次上浮,這樣避免了因乙個數的逆序,而造成巨大的比較。如(2,3,4,…,n-1,n,1),用氣泡排序需要n(n-1)/2次比較,而此排序只要3輪,共比較(n-1)+(n-2)+(n-3)次,第一輪1將上移一位,第二輪1將移到首位,第三輪將發現無資料交換,序列有序而結束。但它同樣是乙個對資料有序性非常敏感的排序演算法,只適合於資料基本有序的排序。

快速排序:它同樣是氣泡排序的改進,它通過一次交換能消除多個逆序,這樣可以減少逆序時所消耗的掃瞄和資料交換次數。在最優情況下,它的排序時間複雜度為o(nlog2n)。即每次劃分序列時,能均勻分成兩個子串。但最差情況下它的時間複雜度將是o(n^2)。即每次劃分子串時,一串為空,另一串為m-1(程式中的100k正序和逆序就正是這樣,如果程式中採用每次取序列中部資料作為劃分點,那將在正序和逆時達到最優)。從100k中正序的結果上看「快速排序」會比「氣泡排序」更慢,這主要是「氣泡排序」中採用了提前結束排序的方法。有的書上這解釋「快速排序」,在理論上講,如果每次能均勻劃分序列,它將是最快的排序演算法,因此稱它作快速排序。雖然很難均勻劃分序列,

但就平均效能而言,它仍是基於關鍵字比較的內部排序演算法中速度最快者。

直接選擇排序:簡單的選擇排序,它的比較次數一定:n(n-1)/2。也因此無論在序列何種情況下,它都不會有優秀的表現(從上100k的正序和反序資料可以發現它耗時相差不多,相差的只是資料移動時間),可見對資料的有序性不敏感。它雖然比較次數多,但它的資料交換量卻很少。所以我們將發現它在一般情況下將快於氣泡排序。

堆排序:由於它在直接選擇排序的基礎上利用了比較結果形成。效率提高很大。它完成排序的總比較次數為o(nlog2n)。它是對資料的有序性不敏感的一種演算法。但堆排序將需要做兩個步驟:-是建堆,二是排序(調整堆)。所以一般在小規模的序列中不合適,但對於較大的序列,將表現出優越的效能。

直接插入排序:簡單的插入排序,每次比較後最多移掉乙個逆序,因此與氣泡排序的效率相同。但它在速度上還是要高點,這是因為在氣泡排序下是進行值交換,而在插入排序下是值移動,所以直接插入排序將要優於氣泡排序。直接插入法也是一種對資料的有序性非常敏感的一種演算法。在有序情況下只需要經過n-1次比較,在最壞情況下,將需要n(n-1)/2次比較。

希爾排序:

增量的選擇將影響希爾排序的效率。但是無論怎樣選擇增量,最後一定要使增量為1,進行一次直接插入排序。但它相對於直接插入排序,由於在子表中每進行一次比較,就可能移去整個經性表中的多個逆序,從而改善了整個排序效能。希爾排序算是一種基於插入排序的演算法,所以對資料有序敏感。

歸併排序:歸併排序是一種非就地排序,將需要與待排序序列一樣多的輔助空間。在使用它對兩個己有序的序列歸併,將有無比的優勢。

其時間複雜度無論是在最好情況下還是在最壞情況下均是o(nlog2n)。

對資料的有序性不敏感。若資料節點資料量大,那將不適合。但可改造成索引操作,效果將非常出色。

基數排序:在程式中採用的是以數值的十進位制位分解,然後對空間採用一次性分配,因此它需要較多的輔助空間(10*n+10), (但我們可以進行其它分解,如以乙個位元組分解,空間採用鍊錶將只需輔助空間n+256)。基數排序的時間是線性的

(即o(n))。由此可見,基數排序非常吸引人,但它也不是就地排序,若節點資料量大時宜改為索引排序。但基數排序有個前提,要關鍵字能象整型、字串這樣能分解,若是浮點型那就不行了。

按平均時間將排序分為類:

(1)

平方階(o(n

2))排序

各類簡單排序,例如直接插入、直接選擇和氣泡排序;

(2)線性對數階

(o(nlog2n))排序

如快速排序

、堆排序

和歸併排序

;(3)

o(n1+§))排序

§是介於

0和1之間的常數。希爾排序便是一種;

(4)線性階(o(n))排序

本程式中的基數排序,此外還有桶、箱排序。

排序方法的選擇

因為不同的排序方法適應不同的應用環境和要求,所以選擇合適的排序方法很重要

(1)若

n較小,可採用直接插入或直接選擇排序。

當記錄規模較小時,直接插入排序較好,它會比選擇更少的比較次數;

但當記錄規模較大時,因為直接選擇移動的記錄數少於直接插人,所以宜用選直接選擇排序。

這兩種都是穩定排序演算法。

(2)若檔案初始狀態基本有序

(指正序

),則應選用直接插人、冒泡或隨機的快速排序為宜

(這裡的隨機是指基準取值的隨機,原因見上的快速排序分析

);這裡快速排序演算法將不穩定。

(3)若

n較大,則應採用時間複雜度為

o(nlog2n)

的排序方法:快速排序、堆排序或歸併排序序。

快速排序是目前基於比較的內部排序中被認為是最好的方法,當待排序的關鍵字是隨機分布時,快速排序的平均時間最短;

堆排序雖不會出現快速排序可能出現的最壞情況。但它需要建堆的過程。這兩種排序都是不穩定的。

歸併排序是穩定的排序演算法,但它有一定數量的資料移動,所以我們可能過與插入排序組合,先獲得一定長度的序列,然後再合併,在效率上將有所提高。

(4)特殊的箱排序、基數排序

它們都是一種穩定的排序演算法,但有一定的侷限性:

1、關鍵字可分解。

2、記錄的關鍵字位數較少,如果密集更好

3、如果是數字時,最好是無符號的,否則將增加相應的對映複雜度,可先將其正負分開排序。

trackback: 

8種排序演算法

學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來說...

8種排序演算法

1.選擇排序 兩層迴圈巢狀,0到n 1選出最小的,與第0個交換,縮小集合為1到n 1,選出最小的,與第乙個交換 時間複雜度 o n2 空間複雜度 因為中間只增加了兩個新變數,儲存最小值和下標,所以空間複雜度為o 1 當陣列為已排序狀態時,仍需要n次比較,最好的情況仍需要o n2 public sta...

8種排序演算法

public class sortcode a j 1 insertnum 找到位置,插入當前元素 system.out.println 直接插入排序後的陣列為 arrays.tostring a 2.希爾排序 針對直接插入排序的下效率問題,有人對次進行了改進與公升級,這就是現在的希爾排序。希爾排序...