第八章 排序
DESCRIPTION
第八章 排序. 8-1 排序簡介 8-2 內部排序法 8-3 外部排序法. 排序簡介. 在排序的過程中,資料的移動方式可分為「直接移動」及「邏輯移動」兩種。 「直接移動」是直接交換儲存資料的位置,而「邏輯移動」並不會移動資料儲存位置,僅改變指向這些資料的輔助指標的值。 資料在經過排序後,會有下列幾點好處:. 1. 資料較容易閱讀。 2. 資料較利於統計及整理。 3. 可大幅減少資料搜尋的時間。. 排序的分類. 內部排序:排序的資料量小,可以完全在記憶體內進 行排序。 2. 外部排序:排序的資料量無法直接在記憶體內進行排 - PowerPoint PPT PresentationTRANSCRIPT
1
第八章 排序
8-1 排序簡介
8-2 內部排序法
8-3 外部排序法
2
排序簡介 在排序的過程中,資料的移動方式可分為「直接
移動」及「邏輯移動」兩種。 「直接移動」是直接交換儲存資料的位置,而
「邏輯移動」並不會移動資料儲存位置,僅改變指向這些資料的輔助指標的值。
資料在經過排序後,會有下列幾點好處:
1. 資料較容易閱讀。2.資料較利於統計及整理。3.可大幅減少資料搜尋的時間。
3
排序的分類
內部排序法有:氣泡排序法、選擇排序法、插入排
序法、合併排序法、快速排序法、堆積排序法、謝
耳排序法、基數排序法等。
外部排序法有:直接合併排序法、 k 路合併法、多相
合併法等。
1. 內部排序:排序的資料量小,可以完全在記憶體內進 行排序。2. 外部排序:排序的資料量無法直接在記憶體內進行排 序,而必須使用到輔助記憶體 ( 如硬碟 ) 。
4
排序演算法分析
演算法是否穩定穩定的排序是指資料在經過排序後,兩個相同鍵值的記錄仍然保持原來的次序,如下例中 7 左的原始位置在 7 右的左邊(所謂 7 左及 7 右是指相同鍵值一個在左一個在右),穩定的排序 (Stable Sort) 後 7 左仍應在 7 右的左邊,不穩定排序則有可能 7 左會跑到 7 右的右邊去。例如:
原始資料順序: 7 左 2 9 7 右 6穩定的排序: 2 6 7 左 7 右 9不穩定的排序: 2 6 7 右 7 左 9
5
時間複雜度 (Time complexity) : 可分為最好情況 (Best Case) 、最壞情況 (Worst Cas
e) 及平均情況 (Average Case) 。 最好情況就是資料已完成排序,例如原本資料已經完
成遞增排序了,如果再進行一次遞增排序所使用的時間複雜度就是最好情況。
最壞情況是指每一鍵值均須重新排列,簡單的例子如原本為遞增排序重新排序成為遞減,就是最壞情況。排序前: 2 3 4 6 8 9排序後: 9 8 6 4 3 2
【這種排序的時間複雜度就是最壞情況】
6
空間複雜度 (Space complexity) : 指演算法在執行過程所需付出的額外記憶體空間。 挑選的排序法必須藉助遞迴的方式來進行,那麼
遞迴過程中會使用到的堆疊就是這個排序法必須付出的額外空間。
排序法所使用到的額外空間愈少,它的空間複雜度就愈佳。
氣泡法在排序過程中僅會用到一個額的空間,在所有的排序演算法中,這樣的空間複雜度就算是最好的。
7
內部排序法 排序名稱 排序特性
簡單排序法
1.氣泡排序法 (Bubble Sort)
(1)穩定排序法(2)空間複雜度為最佳,只需一個額外空間 O(1)
2.選擇排序法 (Selection Sort)
(1)不穩定排序法(2)空間複雜度為最佳,只需一個額外空間 O(1)
3.插入排序法 (Insertion Sort)
(1)穩定排序法(2)空間複雜度為最佳,只需一個額外空間 O(1)
4.謝耳排序法 (Shell Sort)
(1)穩定排序法(2)空間複雜度為最佳,只需一個額外空間 O(1)
8
高等排序法
1.快速排序法 (Quick Sort)
(1)不穩定排序法(2)空間複雜度最差 O(n)最佳 O(log2n)
2.堆積排序法 (Heap Sort)
(1)不穩定排序法(2)空間複雜度為最佳,只需一個額外空間 O(1)
3.基數排序法 (Radix Sort)
(1)穩定排序法(2)空間複雜度為 O(np), n為原始資料的個數, p為基底
9
氣泡排序法
氣泡排序法又稱為交換排序法,是由觀察水中氣泡變化構思而成,氣泡隨著水深壓力而改變。
氣泡排序法的比較方式是由第一個元素開始,比較相鄰元素大小,若大小順序有誤,則對調後再進行下一個元素的比較。
如此掃瞄過一次之後就可確保最後一個元素是位於正確的順序。
接著再逐步進行第二次掃瞄,直到完成所有元素的排序關係為止。
10
氣泡排序法演算流程
由小到大排序:
11
第一次掃瞄會先拿第一個元素 6 和第二個元素 4作比較,如果第二個元素小於第一個元素,則作交換的動作。
接著拿 6 和 9 作比較,就這樣一直比較並交換,到第 4 次比較完後即可確定最大值在陣列的最後面。
12
第二次掃瞄亦從頭比較起,但因最後一個元素在第一次掃瞄就已確定是陣列最大值,故只需比較 3次即可把剩餘陣列元素的最大值排到剩餘陣列的最後面。
13
第三次掃瞄完,完成三個值的排序
第四次掃瞄完,即可完成所有排序 由此可知 5 個元素的氣泡排序法必須執行 5-1 次
掃瞄,第一次掃瞄需比較 5-1 次,共比較 4+3+2+1=10 次
14
氣泡法分析
2
)1( nn1. 最壞清況及平均情況均需比較: (n-1)+(n-2)+(n-3) + …+3+2+1= 次;時間複雜度為 O(n2) ,最好
情 況只需完成一次掃瞄,發現沒有做交換的動作則表 示已經排序完成,所以只做了 n-1 次比較,時間複
雜 度為 O(n) 。2. 由於氣泡排序為相鄰兩者相互比較對調,並不會更 改其原本排列的順序,所以是穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於資料量小或有部份資料已經過排序。
15
範例程式: ch08_01.java
16
範例程式: ch08_02.java
17
選擇排序法 一為在所有的資料中,當由大至小排序,則將最
大值放入第一位置;若由小至大排序時,則將最大值放入位置末端。
例如當 N筆資料需要由大至小排序時,首先以第一個位置的資料,依次向 2 、 3 、 4 …N 個位置的資料作比較。
如果資料大於或等於其中一個位置,則兩個位置的資料不變;若小於其中一個位置,則兩個位置的資料互換。
18
排序法的演算流程
首先找到此數列中最小值後與第一個元素交換。
19
接著從第二個值找起,找到此數列中 ( 不包含第一個 ) 的最小值,再和第二個值交換。
接著從第三個值找起,找到此數列中 ( 不包含第一、二個 ) 的最小值,再和第三個值交換。
最後從第四個值找起,找到此數列中 ( 不包含第一、二、三個 ) 的最小值,再和第四個值交換,則此排序完成。
20
選擇法分析
2
)1( nn
1. 無論是最壞清況、最佳情況及平均情況都需要找到 最大值 (或最小值 ) ,因此其比較次數為: (n-1)+(n-
2) +(n-3)+…+3+2+1= 次;時間複雜度為 O(n2)2. 由於選擇排序是以最大或最小值直接與最前方未排
序 的鍵值交換,資料排列順序很有可能被改變,故不是 穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於資料量小或有部份資料已經過排序。
21
範例程式: ch08_03.java
22
插入排序法 插入排序法 (Insert Sort) 是將陣列中的元素,逐一與已排序好的資料作比較,再將該陣列元素插入適當的位置。如以下說明:
由小到大排序:原始值: 6 4 9 8 3
23
插入法分析
2
)1( nn1. 最壞及平均清況需比較 (n-1)+(n-2)+(n-3)+…+3+2+
1 = 次;時間複雜度為 O(n2) ,最好情況時間複雜 度為: O(n)2. 插入排序是穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於大部份資料已經過排序或已排序資 料庫新增資料後進行排序。5. 插入排序法會造成資料的大量搬移,所以建議在鏈結
串列上使用。
24
範例程式: ch08_04.java
25
謝耳排序法
「謝耳排序法」是 D. L. Shell 在 1959年 7月所發明的一種排序法,而該排序法直接以發明者命名。
其排序法的原理有點像是插入排序法,但它可以減少資料搬移的次數。
排序的原則是將資料區分成特定間隔的幾個小區塊,以插入排序法排完區塊內的資料後再漸漸減少間隔的距離。
26
謝耳法分析
1.任何情況的時間複雜度均為 O(n3/2) 。2. 謝耳排序法和插入排序法一樣,都是穩定排序。3. 只需一個額外空間,所以空間複雜度是最佳。4. 此排序法適用於資料大部份都已排序完成的情況。
27
範例程式: ch08_05.java
28
合併排序法 合併排序法 (Merge Sort) 的工作原理乃是針對
已排序好的二個或二個以上的檔案,經由合併的方式,將其組合成一個大的且已排序好的檔案。
底下是數列 3,1,4,7,5,9,6,2 合併排序法的的排序過程:
29
條列方式的步驟
1. 將 N 個長度為 1 的檔案合併成 N/2 個已排序妥當且
長度為 2 的檔案。2. 將 N/2 個長度為 2 的檔案合併成 N/4 個已排序妥當
且長度為 4 的檔案。3. 將 N/4 個長度為 4 的檔案合併成 N/8 個已排序妥當
且長度為 8 的檔案。4. 將 N/2i-1 個長度為 2i-1 的檔案合併成 N/2i 個已
排序 妥當且長度為 2i 的檔案。
30
合併排序法:
1. 合併排序法 n筆資料一般需要約 log2n 次處理, 每次處理的時間複雜度為 O(n) ,所以合併排序 法的最佳情況、最差情況及平均情況複雜度為 O(nlogn) 。2. 由於在排序過程中需要一個與檔案大小同樣的 額外空間,故其空間複雜度 O(n) 。3. 是一個穩定 (stable) 的排序方式。
31
快速排序法 快速排序法又稱分割交換排序法,是目前公認最
佳的排序法。假設有 n筆記錄 R1,R2,R3…Rn ,其鍵值為 k1,k2,k3…kn 。快速排序法的步驟如下:
1. 取 K 為第一筆鍵值。2. 由左向向找出一個鍵值 Ki 使得 Ki>K 。3. 由右向左找出一個鍵值 Kj 使得 Kj<K 。4. 若 i<j 則 Ki與 Kj 交換,並繼續步驟的執行。5. 若 ij 則將 K與 Kj 交換,並以 j 為基準點將資料分為
左右兩 部份。並以遞迴方式分別為左右兩半進行排序,直至 完成排序。
32
快速法分析
1. 在最快及平均情況下,時間複雜度為 O(nlog2n) 。 最壞情況就是每次挑中的中間值不是最大就是最 小,其時間複雜度為 O(n2) 。2. 快速排序法不是穩定排序法。3. 在最差的情況下,空間複雜度為 O(n) ,而最佳情
況 為 O(log2n) 。4. 快速排序法是平均執行時間最快的排序法。
33
範例程式: ch08_06.java
34
堆積排序法 堆積是一種特殊的二元樹,可分為最大堆積樹
及最小堆積樹兩種。 最大堆積樹滿足以下 3 個條件:
最小堆積樹則具備以下 3 個條件:
1. 它是一個完整二元樹。2. 所有節點的值都大於或等於它左右子節點的值。3.樹根是堆積樹中最大的。
1. 它是一個完整二元樹。2. 所有節點的值都小於或等於它左右子節點的值。3.樹根是堆積樹中最小的。
35
堆積法分析
① 在所有情況下,時間複雜度均為 O(nlogn) 。② 堆積排序法不是穩定排序法。③ 只需要一額外的空間,空間複雜度為 O(1) 。
36
範例程式: ch08_07.java
37
基數排序法
基數排序法依比較的方向可分為最有效鍵優先 (M
ost Significant Digit First:MSD) 和最無效鍵優先(Least Significant Digit First:LSD) 兩種。
MSD 法是從最左邊的位數開始比較,而 LSD 則是從最右邊的位數開始比較。
底下的範例我們以 LSD將三位數的整數資料來加以排序,它是依個位數、十位數、百位數來進行排序。
38
原始資料:
步驟一:把每個整數依其個位數字放到串列中:26 95 7 34 60 168 171 259 372 45 88 133
個位數字 0 1 2 3 4 5 6 7 8 9
資料 60 171 372 133 34 9545
59 7 16888
59259
39
合併後成為:
步驟二:再依其十位數字,依序放到串列中:
60 171 372 133 34 95 45 7 168 88 59 259
十位數字 0 1 2 3 4 5 6 7 8 9
資料
7 133
34
45 59259
60168
171
372
88 95
40
合併後成為:
步驟二:再依其百位數字,依序放到串列中:7 133 34 45 59 259 60 168 171 372 88 95
百位數字 0 1 2 3 4 5 6 7 8 9
資料
7344559608895
133
168
171
259
372
41
最後合併即完成排序:
基數法分析: 7 34 45 59 60 88 95 133 168 171 259 372
1. 在所有情況下,時間複雜度均為 O(nlogpk) , k 是原始
資料的最大值。2. 基數排序法是穩定排序法。3. 基數排序法會使用到很大的額外空間來存放串列資 料,其空間複雜度為 O(n*p) , n 是原始資料的個數,
p 是資料字元數;如上例中,資料的個數 n=12 ,字元數 p=3 。4. 若 n很大, p固定或很小,此排序法將很有效率。
42
範例程式: ch08_08.java
43
外部排序法
外部儲存裝置又可依照存取方式分為兩種方式,如循序存取 ( 如磁帶 )或隨機存取 ( 如磁碟 ) 。
而隨機存取的檔案就像是陣列,資料存取方便,所以相對的排序也會比循序存取快一些。
最常使用的就是合併排序法,它適用於循序存取的檔案。
44
直接合併排序法
直接合併排序法 (Direct Merge Sort) 是外部儲存裝置最常用的排序方法。它可以分為兩個步驟:
1.將欲排序的檔案分為幾個可以載入記憶體空間大 小的小檔案,再使用內部排序法將各檔案內的資 料排序。2.將第一步驟所建立的小檔案每二個合併成一個檔 案。兩兩合併後,把所有檔案合併成一個檔案後 就可以完成排序了。
45
範例程式: ch08_09.java
以下的程式是直接把兩個已經排序好的檔案合併與排序成一個檔案。
46
範例程式: ch08_10.java
47
k 路合併法 (k-Way Merge)
它所需要的時間儘需 logkn ,也就是處理輸出入時間減少許多,排序的速度也因此可以加快。
首先我門來描述利用 3 路合併 (3-way merge) 來處理 27 個行程 (Runs) 的示意圖:
48
多相合併法 (Polyphase Merge)
它可以使用少於 2k 個磁碟,卻能正確無誤地執行 k-way 合併。以下示範了如何進行多相合併。
下圖共有 21 個 runs ,使用 2-way 合併及 3個磁帶 T1 、 T2 、 T3 來進行合併,假設這 21個行程 ( 已排序完畢,且令其長度為 1) 的表示方為 Sn ,其中 S 為行程大小, n 為長度相同 run 的個數。
例如 8 個 runs且長度為 2 ,可表示成 28 。
49
2-way 及 3 個磁碟的多項合併 Phas
eT1 T2 T3 合併狀況說明
1 113 18 empty起始分佈情況
2 15 empty
28 將 T1及 T2長度為 1的 8個行程合併到 T3,其長
度變成 23 empt
y35 23 將 T15個長度為 1的行程和 T35個長度為 2
的行程,合併到 T2,其長度變成 3
4 53 32 empty將 T23個長度為 3的行程和 T33個長度為 2的行
程 ,合併到 T1,其長度變成 55 51 empt
y82 將 T12個長度為 5的行程和 T22個長度為 3
的行程 ,合併到 T3,其長度變成 8
6 empty
131 81 將 T11個長度為 5的行程和 T31個長度為 8的行
程,合併到 T2,其長度變成 137 211 empt
yempt
y將 T21個長度為 13的行程和 T31個長度為 8的
行程,合併到 T1,其長度變成 21