前幾天應乙個朋友的要求,幫他完成了資料排序的乙個作業。覺得很有給大家參考的價值,所以經過他同意,作了些修改帖了上來。源**見附件,**中實現了8種排序演算法,各演算法名稱見下表或見原始碼。執行程式時,將需要你輸入一數值,以確定對多少隨機數進行排序。然後將會顯示各排序演算法的耗時。並且你可選擇時否進行正序和反序測試。
由於水平有限,可能存在一些錯誤,還請各位多多指點!
通過實驗我們可將結果列入下表。
以下是vc6.0(release)+win2000pro+128mddr+p4(1.6g)
因為在多工作業系統下,系統將進行程序式排程,影響實驗結果。以下是經過稍微修正過的值。如果要取得更準確的值,我們得多次實驗求其平均值。
排序演算法實驗比較(單位:秒)
n 方法1k
10k
100k
200k
100k 正序
逆序氣泡排序0
0.422
44.790
188.462 0
31.459
shaker排序0
0.281
30.335
131.771 0
27.568
快速排序0
0 0.016
0.047
5.095
7.002
直接選擇排序0
0.141
16.878
79.332
16.785
33.242
堆排序0
0 0.031
0.109
0.031
0.015
直接插入0
0.047
8.705
57.800 0
24.865
shell排序0
00.047
0.110
0.015
0.032
歸併排序0
0 0.031
0.094
0.032
0.046
基數排序0
0 0.47
0.109
0.047
演算法與結果聯合分析
氣泡排序:在最優情況下只需要經過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(n2))排序
各類簡單排序,例如直接插入、直接選擇和氣泡排序;
(2) 線性對數階(o(nlog2n))排序
如快速排序、堆排序和歸併排序;
(3) o(n1+§))排序
§是介於0和1之間的常數。希爾排序便是一種;
(4) 線性階(o(n))排序
本程式中的基數排序,此外還有桶、箱排序。
排序方法的選擇
因為不同的排序方法適應不同的應用環境和要求,所以選擇合適的排序方法很重要
(1)若n較小,可採用直接插入或直接選擇排序。
當記錄規模較小時,直接插入排序較好,它會比選擇更少的比較次數;
但當記錄規模較大時,因為直接選擇移動的記錄數少於直接插人,所以宜用選直接選擇排序。
這兩種都是穩定排序演算法。
(2)若檔案初始狀態基本有序(指正序),則應選用直接插人、冒泡或隨機的快速排序為宜(這裡的隨機是指基準取值的隨機,原因見上的快速排序分析);這裡快速排序演算法將不穩定。
(3)若n較大,則應採用時間複雜度為o(nlog2n)的排序方法:快速排序、堆排序或歸併排序序。
快速排序是目前基於比較的內部排序中被認為是最好的方法,當待排序的關鍵字是隨機分布時,快速排序的平均時間最短;
堆排序雖不會出現快速排序可能出現的最壞情況。但它需要建堆的過程。這兩種排序都是不穩定的。
歸併排序是穩定的排序演算法,但它有一定數量的資料移動,所以我們可能過與插入排序組合,先獲得一定長度的序列,然後再合併,在效率上將有所提高。
(4)特殊的箱排序、基數排序
它們都是一種穩定的排序演算法,但有一定的侷限性:
1、關鍵字可分解。
2、記錄的關鍵字位數較少,如果密集更好
3、如果是數字時,最好是無符號的,否則將增加相應的對映複雜度,可先將其正負分開排序。
資料結構學習總結
了解資料,資料項,資料元素,資料物件的關係。資料元素 組成資料的,具有一定意義的基本單位,在計算機中做整體處理,也稱為記錄。乙個資料元素可以由多個資料項組成。資料物件 資料相同的資料元素的集合,是資料的子集。有的書上也成為資料物件和例項,結合的理解。資料結構可以分為 物理結構和邏輯結構 邏輯結構 集...
資料結構學習總結
隨著2015年的結束,資料結構這門課程也即將結束,這乙個學期跟著賀老師一起通過翻轉課堂的方式學習既新鮮也很慶幸。對這一學期資料結構的學習我想說一說我的感受。這學期資料結構 學了線性結構 樹 圖等等 線性結構包括線性表 棧 佇列 串 陣列 廣義表等 遞迴是程式設計中很重要的一種工具 也是我需要掌握的乙...
資料結構學習總結
第一章是緒論,介紹了資料結構的基本概念,資料結構有邏輯結構和儲存結構兩種 第二章為線性表,介紹了線性表的兩種儲存結構 順序表和煉表與其基本運算演算法的實現,鍊錶又包括單鏈表 雙鏈表 迴圈列表等多種形式 第三章為棧和佇列,介紹這兩種特殊的線性結構的概念與應用 第四章是串,介紹串,包括順序串和鏈串的概念...