第八章 排序

49
1 第第第 第第 8-1 第第第第 8-2 第第第第第 8-3 第第第第第

Upload: loc

Post on 04-Jan-2016

34 views

Category:

Documents


0 download

DESCRIPTION

第八章 排序. 8-1 排序簡介 8-2 內部排序法 8-3 外部排序法. 排序簡介. 在排序的過程中,資料的移動方式可分為「直接移動」及「邏輯移動」兩種。 「直接移動」是直接交換儲存資料的位置,而「邏輯移動」並不會移動資料儲存位置,僅改變指向這些資料的輔助指標的值。 資料在經過排序後,會有下列幾點好處:. 1. 資料較容易閱讀。 2. 資料較利於統計及整理。 3. 可大幅減少資料搜尋的時間。. 排序的分類. 內部排序:排序的資料量小,可以完全在記憶體內進 行排序。 2. 外部排序:排序的資料量無法直接在記憶體內進行排 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第八章 排序

1

第八章 排序

8-1 排序簡介

8-2 內部排序法

8-3 外部排序法

Page 2: 第八章 排序

2

排序簡介 在排序的過程中,資料的移動方式可分為「直接

移動」及「邏輯移動」兩種。 「直接移動」是直接交換儲存資料的位置,而

「邏輯移動」並不會移動資料儲存位置,僅改變指向這些資料的輔助指標的值。

資料在經過排序後,會有下列幾點好處:

1. 資料較容易閱讀。2.資料較利於統計及整理。3.可大幅減少資料搜尋的時間。

Page 3: 第八章 排序

3

排序的分類

內部排序法有:氣泡排序法、選擇排序法、插入排

序法、合併排序法、快速排序法、堆積排序法、謝

耳排序法、基數排序法等。

外部排序法有:直接合併排序法、 k 路合併法、多相

合併法等。

1. 內部排序:排序的資料量小,可以完全在記憶體內進 行排序。2. 外部排序:排序的資料量無法直接在記憶體內進行排 序,而必須使用到輔助記憶體 ( 如硬碟 ) 。

Page 4: 第八章 排序

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

Page 5: 第八章 排序

5

時間複雜度 (Time complexity) : 可分為最好情況 (Best Case) 、最壞情況 (Worst Cas

e) 及平均情況 (Average Case) 。 最好情況就是資料已完成排序,例如原本資料已經完

成遞增排序了,如果再進行一次遞增排序所使用的時間複雜度就是最好情況。

最壞情況是指每一鍵值均須重新排列,簡單的例子如原本為遞增排序重新排序成為遞減,就是最壞情況。排序前: 2 3 4 6 8 9排序後: 9 8 6 4 3 2

【這種排序的時間複雜度就是最壞情況】

Page 6: 第八章 排序

6

空間複雜度 (Space complexity) : 指演算法在執行過程所需付出的額外記憶體空間。 挑選的排序法必須藉助遞迴的方式來進行,那麼

遞迴過程中會使用到的堆疊就是這個排序法必須付出的額外空間。

排序法所使用到的額外空間愈少,它的空間複雜度就愈佳。

氣泡法在排序過程中僅會用到一個額的空間,在所有的排序演算法中,這樣的空間複雜度就算是最好的。

Page 7: 第八章 排序

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)

Page 8: 第八章 排序

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為基底

Page 9: 第八章 排序

9

氣泡排序法

氣泡排序法又稱為交換排序法,是由觀察水中氣泡變化構思而成,氣泡隨著水深壓力而改變。

氣泡排序法的比較方式是由第一個元素開始,比較相鄰元素大小,若大小順序有誤,則對調後再進行下一個元素的比較。

如此掃瞄過一次之後就可確保最後一個元素是位於正確的順序。

接著再逐步進行第二次掃瞄,直到完成所有元素的排序關係為止。

Page 10: 第八章 排序

10

氣泡排序法演算流程

由小到大排序:

Page 11: 第八章 排序

11

第一次掃瞄會先拿第一個元素 6 和第二個元素 4作比較,如果第二個元素小於第一個元素,則作交換的動作。

接著拿 6 和 9 作比較,就這樣一直比較並交換,到第 4 次比較完後即可確定最大值在陣列的最後面。

Page 12: 第八章 排序

12

第二次掃瞄亦從頭比較起,但因最後一個元素在第一次掃瞄就已確定是陣列最大值,故只需比較 3次即可把剩餘陣列元素的最大值排到剩餘陣列的最後面。

Page 13: 第八章 排序

13

第三次掃瞄完,完成三個值的排序

第四次掃瞄完,即可完成所有排序 由此可知 5 個元素的氣泡排序法必須執行 5-1 次

掃瞄,第一次掃瞄需比較 5-1 次,共比較 4+3+2+1=10 次

Page 14: 第八章 排序

14

氣泡法分析

2

)1( nn1. 最壞清況及平均情況均需比較: (n-1)+(n-2)+(n-3) + …+3+2+1= 次;時間複雜度為 O(n2) ,最好

情 況只需完成一次掃瞄,發現沒有做交換的動作則表 示已經排序完成,所以只做了 n-1 次比較,時間複

雜 度為 O(n) 。2. 由於氣泡排序為相鄰兩者相互比較對調,並不會更 改其原本排列的順序,所以是穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於資料量小或有部份資料已經過排序。

Page 15: 第八章 排序

15

範例程式: ch08_01.java

Page 16: 第八章 排序

16

範例程式: ch08_02.java

Page 17: 第八章 排序

17

選擇排序法 一為在所有的資料中,當由大至小排序,則將最

大值放入第一位置;若由小至大排序時,則將最大值放入位置末端。

例如當 N筆資料需要由大至小排序時,首先以第一個位置的資料,依次向 2 、 3 、 4 …N 個位置的資料作比較。

如果資料大於或等於其中一個位置,則兩個位置的資料不變;若小於其中一個位置,則兩個位置的資料互換。

Page 18: 第八章 排序

18

排序法的演算流程

首先找到此數列中最小值後與第一個元素交換。

Page 19: 第八章 排序

19

接著從第二個值找起,找到此數列中 ( 不包含第一個 ) 的最小值,再和第二個值交換。

接著從第三個值找起,找到此數列中 ( 不包含第一、二個 ) 的最小值,再和第三個值交換。

最後從第四個值找起,找到此數列中 ( 不包含第一、二、三個 ) 的最小值,再和第四個值交換,則此排序完成。

Page 20: 第八章 排序

20

選擇法分析

2

)1( nn

1. 無論是最壞清況、最佳情況及平均情況都需要找到 最大值 (或最小值 ) ,因此其比較次數為: (n-1)+(n-

2) +(n-3)+…+3+2+1= 次;時間複雜度為 O(n2)2. 由於選擇排序是以最大或最小值直接與最前方未排

序 的鍵值交換,資料排列順序很有可能被改變,故不是 穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於資料量小或有部份資料已經過排序。

Page 21: 第八章 排序

21

範例程式: ch08_03.java

Page 22: 第八章 排序

22

插入排序法 插入排序法 (Insert Sort) 是將陣列中的元素,逐一與已排序好的資料作比較,再將該陣列元素插入適當的位置。如以下說明:

由小到大排序:原始值: 6 4 9 8 3

Page 23: 第八章 排序

23

插入法分析

2

)1( nn1. 最壞及平均清況需比較 (n-1)+(n-2)+(n-3)+…+3+2+

1 = 次;時間複雜度為 O(n2) ,最好情況時間複雜 度為: O(n)2. 插入排序是穩定排序法。3. 只需一個額外的空間,所以空間複雜度為最佳。4. 此排序法適用於大部份資料已經過排序或已排序資 料庫新增資料後進行排序。5. 插入排序法會造成資料的大量搬移,所以建議在鏈結

串列上使用。

Page 24: 第八章 排序

24

範例程式: ch08_04.java

Page 25: 第八章 排序

25

謝耳排序法

「謝耳排序法」是 D. L. Shell 在 1959年 7月所發明的一種排序法,而該排序法直接以發明者命名。

其排序法的原理有點像是插入排序法,但它可以減少資料搬移的次數。

排序的原則是將資料區分成特定間隔的幾個小區塊,以插入排序法排完區塊內的資料後再漸漸減少間隔的距離。

Page 26: 第八章 排序

26

謝耳法分析

1.任何情況的時間複雜度均為 O(n3/2) 。2. 謝耳排序法和插入排序法一樣,都是穩定排序。3. 只需一個額外空間,所以空間複雜度是最佳。4. 此排序法適用於資料大部份都已排序完成的情況。

Page 27: 第八章 排序

27

範例程式: ch08_05.java

Page 28: 第八章 排序

28

合併排序法 合併排序法 (Merge Sort) 的工作原理乃是針對

已排序好的二個或二個以上的檔案,經由合併的方式,將其組合成一個大的且已排序好的檔案。

底下是數列 3,1,4,7,5,9,6,2 合併排序法的的排序過程:

Page 29: 第八章 排序

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 的檔案。

Page 30: 第八章 排序

30

合併排序法:

1. 合併排序法 n筆資料一般需要約 log2n 次處理, 每次處理的時間複雜度為 O(n) ,所以合併排序 法的最佳情況、最差情況及平均情況複雜度為 O(nlogn) 。2. 由於在排序過程中需要一個與檔案大小同樣的 額外空間,故其空間複雜度 O(n) 。3. 是一個穩定 (stable) 的排序方式。

Page 31: 第八章 排序

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 為基準點將資料分為

左右兩 部份。並以遞迴方式分別為左右兩半進行排序,直至 完成排序。

Page 32: 第八章 排序

32

快速法分析

1. 在最快及平均情況下,時間複雜度為 O(nlog2n) 。 最壞情況就是每次挑中的中間值不是最大就是最 小,其時間複雜度為 O(n2) 。2. 快速排序法不是穩定排序法。3. 在最差的情況下,空間複雜度為 O(n) ,而最佳情

況 為 O(log2n) 。4. 快速排序法是平均執行時間最快的排序法。

Page 33: 第八章 排序

33

範例程式: ch08_06.java

Page 34: 第八章 排序

34

堆積排序法 堆積是一種特殊的二元樹,可分為最大堆積樹

及最小堆積樹兩種。 最大堆積樹滿足以下 3 個條件:

最小堆積樹則具備以下 3 個條件:

1. 它是一個完整二元樹。2. 所有節點的值都大於或等於它左右子節點的值。3.樹根是堆積樹中最大的。

1. 它是一個完整二元樹。2. 所有節點的值都小於或等於它左右子節點的值。3.樹根是堆積樹中最小的。

Page 35: 第八章 排序

35

堆積法分析

① 在所有情況下,時間複雜度均為 O(nlogn) 。② 堆積排序法不是穩定排序法。③ 只需要一額外的空間,空間複雜度為 O(1) 。

Page 36: 第八章 排序

36

範例程式: ch08_07.java

Page 37: 第八章 排序

37

基數排序法

基數排序法依比較的方向可分為最有效鍵優先 (M

ost Significant Digit First:MSD) 和最無效鍵優先(Least Significant Digit First:LSD) 兩種。

MSD 法是從最左邊的位數開始比較,而 LSD 則是從最右邊的位數開始比較。

底下的範例我們以 LSD將三位數的整數資料來加以排序,它是依個位數、十位數、百位數來進行排序。

Page 38: 第八章 排序

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

Page 39: 第八章 排序

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

Page 40: 第八章 排序

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

Page 41: 第八章 排序

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固定或很小,此排序法將很有效率。

Page 42: 第八章 排序

42

範例程式: ch08_08.java

Page 43: 第八章 排序

43

外部排序法

外部儲存裝置又可依照存取方式分為兩種方式,如循序存取 ( 如磁帶 )或隨機存取 ( 如磁碟 ) 。

而隨機存取的檔案就像是陣列,資料存取方便,所以相對的排序也會比循序存取快一些。

最常使用的就是合併排序法,它適用於循序存取的檔案。

Page 44: 第八章 排序

44

直接合併排序法

直接合併排序法 (Direct Merge Sort) 是外部儲存裝置最常用的排序方法。它可以分為兩個步驟:

1.將欲排序的檔案分為幾個可以載入記憶體空間大 小的小檔案,再使用內部排序法將各檔案內的資 料排序。2.將第一步驟所建立的小檔案每二個合併成一個檔 案。兩兩合併後,把所有檔案合併成一個檔案後 就可以完成排序了。

Page 45: 第八章 排序

45

範例程式: ch08_09.java

以下的程式是直接把兩個已經排序好的檔案合併與排序成一個檔案。

Page 46: 第八章 排序

46

範例程式: ch08_10.java

Page 47: 第八章 排序

47

k 路合併法 (k-Way Merge)

它所需要的時間儘需 logkn ,也就是處理輸出入時間減少許多,排序的速度也因此可以加快。

首先我門來描述利用 3 路合併 (3-way merge) 來處理 27 個行程 (Runs) 的示意圖:

Page 48: 第八章 排序

48

多相合併法 (Polyphase Merge)

它可以使用少於 2k 個磁碟,卻能正確無誤地執行 k-way 合併。以下示範了如何進行多相合併。

下圖共有 21 個 runs ,使用 2-way 合併及 3個磁帶 T1 、 T2 、 T3 來進行合併,假設這 21個行程 ( 已排序完畢,且令其長度為 1) 的表示方為 Sn ,其中 S 為行程大小, n 為長度相同 run 的個數。

例如 8 個 runs且長度為 2 ,可表示成 28 。

Page 49: 第八章 排序

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