1 / 82

Chapter 8

Chapter 8. 排序. 8.1 前言. 排序 (Sort) 乃是將檔案中的 紀錄 (Records) 依照特定 欄位 (Field) ( 或稱屬性 (Attribute)) 的資料值來重新排列順序 排序時須指定: 用 哪一個欄位 的資料值來排序 按 遞增 (Ascending Order) 或 按 遞減 (Descending Order) 之順序來排序 鍵 (Key) 用來排序的欄位 鍵值 (Key Value) 欄位的資料值. 8.2 檔案、紀錄、欄位、索引與排序. 檔案 資料表 欄位、屬性、資料行 紀錄、資料列 索引.

Download Presentation

Chapter 8

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 8 排序 資料結構導論 - C語言實作

  2. 8.1 前言 • 排序(Sort) • 乃是將檔案中的紀錄(Records)依照特定欄位(Field)(或稱屬性(Attribute))的資料值來重新排列順序 • 排序時須指定: • 用哪一個欄位的資料值來排序 • 按遞增(Ascending Order)或按遞減(Descending Order)之順序來排序 • 鍵(Key) • 用來排序的欄位 • 鍵值(Key Value) • 欄位的資料值 資料結構導論 - C語言實作

  3. 8.2 檔案、紀錄、欄位、索引與排序 • 檔案 • 資料表 • 欄位、屬性、資料行 • 紀錄、資料列 • 索引 資料結構導論 - C語言實作

  4. 8.2 檔案、紀錄、欄位、索引與排序 • 資料表(Table) 資料結構導論 - C語言實作

  5. 8.2 檔案、紀錄、欄位、索引與排序 • 索引(Index) 資料結構導論 - C語言實作

  6. 8.2 檔案、紀錄、欄位、索引與排序 • 索引(Index) 資料結構導論 - C語言實作

  7. 8.3 內部排序法(Internal Sort) • 內部排序法 • 利用記憶體來排序 • 速度快 • 外部排序法 • 利用磁碟、磁帶等輔助記憶體來排序 • 速度慢 資料結構導論 - C語言實作

  8. 8.3 內部排序法(Internal Sort) • 8.3.1.  氣泡浮昇排序法(Bubble Sort) • 8.3.2.  挑選排序法(Selection Sort) • 8.3.3.  插入排序法(Insertion Sort) • 8.3.4.  謝耳排序法(Shell Sort) • 8.3.5.  快速排序法(Quick Sort) • 8.3.6.  樹排序法 (Tree Sort) • 8.3.7.  堆積排序法(Heap Sort) • 8.3.8.  合併排序法(Merge Sort) • 8.3.9. 基數排序法(Radix Sort) 資料結構導論 - C語言實作

  9. 8.3.1.  氣泡浮昇排序法(Bubble Sort) • 將編號為0、1、2、...、n-1的n筆記錄按照「鍵值不遞減」的順序(Non-decreasing Order)加以排列的步驟如下: 步驟1:將n筆記錄的鍵值儲存到陣列d[n]中,其中d[0]儲存第0號記錄的鍵值、d[1]儲存第1號記錄的鍵值、…、d[n-1]儲存第n-1號記錄的鍵值 資料結構導論 - C語言實作

  10. 8.3.1.  氣泡浮昇排序法(Bubble Sort) 步驟2:重複執行步驟3共計n-1回合,其中若有任一回合完全沒有發生陣列元素值「交換」的情形時,就執行步驟4 步驟3:依序比較陣列d中相鄰兩元素之鍵值;即第i回合須依序比較(d[0]和d[1])、(d[1]和d[2])、(d[2]和d[3])、...、(d[n-i+1]和d[n-i]);若前面的元素d[x]大於後面的元素d[x+1],則立刻將d[x]與d[x+1]之值「交換」 步驟4:列印出陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-i]之值 資料結構導論 - C語言實作

  11. 8.3.1.  氣泡浮昇排序法(Bubble Sort) 【例1】氣泡浮昇排序法 • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值{83,66,55,21,88,18,88*,99}已經儲存在一維陣列d[8]中。 • 按照「鍵值不遞減」的順序加以排序 資料結構導論 - C語言實作

  12. 8.3.1.  氣泡浮昇排序法(Bubble Sort) • 第1回合相鄰元素兩兩比較、交換位置之分解動作 資料結構導論 - C語言實作

  13. 8.3.1.  氣泡浮昇排序法(Bubble Sort) 資料結構導論 - C語言實作

  14. 8.3.1.  氣泡浮昇排序法(Bubble Sort) • 穩定排序(Stable Sort) : • 相同鍵值的資料於排序後仍然保持排序前之前後關係者 • 不穩定排序(Unstable Sort) 資料結構導論 - C語言實作

  15. 8.3.2.  挑選排序法(Selection Sort) • 挑選排序法也是透過「鍵值交換」來達成排序的目的。 • 第1回合從n筆鍵值中挑選出最小的鍵值,然後將它與d[0]交換位置。 • 第2回合從剩下的n-1筆鍵值中挑選出最小的鍵值,然後將它與d[1]交換位置。 • 第3回合從剩下的n-2筆鍵值中挑選出最小的鍵值,然後將它與d[2]交換位置。 • 第n-1回合從剩下的2筆鍵值中挑選出最小的鍵值,然後將它與d[n-2]交換位置。 • 剩下的1筆鍵值便是所有鍵值中的最大者,它自然存放在d[n-1]位置。 資料結構導論 - C語言實作

  16. 8.3.2.  挑選排序法(Selection Sort) • 採用挑選排序法將編號為0、1、2、...、n-1的n筆紀錄按照「鍵值不遞減」的順序加以排列的步驟如下: 步驟1:將n筆紀錄的鍵值儲存到陣列d[n]中,其中d[0]儲存第0號紀錄的鍵值、d[1]儲存第1號紀錄的鍵值、…、d[n-1]儲存第n-1號紀錄的鍵值。 步驟2:重複執行步驟3,共計n-1回合。 步驟3:第i回合(i從1開始),從陣列d[i-1]至d[n-1]中找出最小的鍵值(設d[x]),然後將d[x]與d[i-1]之鍵值交換。 步驟4:列印出陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-1]之值。 資料結構導論 - C語言實作

  17. 8.3.2.  挑選排序法(Selection Sort) 【例1】挑選排序法 • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值{83,66,55,21,88,18,88*,99}已經儲存在一維陣列d[8]中。 • 如果我們採用「挑選排序法」來將該組資料依「鍵值不遞減」的順序排序,總共須要7個回合,每一回合排序後之結果詳如表8.2所示。 資料結構導論 - C語言實作

  18. 8.3.2.  挑選排序法(Selection Sort) 資料結構導論 - C語言實作

  19. 8.3.2.  挑選排序法(Selection Sort) • 第1回合, • 從d[0]到d[7]找出最小者,結果找到d[5]=18最小,將d[5]之值與d[0]之值交換。 • 本回合排序後,最小之鍵值已經被安排到d[0]位置。 • 第2回合, • 從d[1]到d[7]找出最小者,結果找到d[3]=21最小,將d[3]之值與d[1]之值交換。 • 本回合排序後,第2小之鍵值已經被安排到d[1]位置。 • 第3回合, • 從d[2]到d[7]找出最小者,結果找到d[2]=55最小,將d[2]之值與d[2]之值交換。 • 本回合排序後,第3小之鍵值已經被安排到d[2]位置。 資料結構導論 - C語言實作

  20. 8.3.3.  插入排序法(Insertion Sort) • 插入排序法的觀念是將n筆鍵值區分成「已排序」和「未排序」的A、B兩群 • A群:已經排序好了 • B群:尚未排序 • 排序時從B群取出一筆資料然後將之插入到A群的正確位置,重複這個動作直到B群空無資料,此時A群便是完整排序的資料了。 資料結構導論 - C語言實作

  21. 8.3.3.  插入排序法(Insertion Sort) 資料結構導論 - C語言實作

  22. 8.3.3.  插入排序法(Insertion Sort) • 採用插入排序法將編號為0、1、2、...、n-1的n筆紀錄按照「鍵值不遞減」的順序加以排列的步驟如下: 步驟1:將n筆紀錄的鍵值儲存到陣列d[n]中,其中d[0]儲存第0號紀錄的鍵值、d[1]儲存第1號紀錄的鍵值、…、d[n-1]儲存第n-1號紀錄的鍵值。 步驟2:重複執行步驟3共計n-1回合。 步驟3:第i回合(i從1開始),將陣列d[i]插入到其前面d[0]至d[i-1]的正確位置。 步驟4:列印出陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-1]之值。 資料結構導論 - C語言實作

  23. 8.3.3.  插入排序法(Insertion Sort) 【例1】插入排序法 • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值{83,66,55,21,88,18,88*,99}已經儲存在一維陣列d[8]中。 • 如果我們採用「插入排序法」來將該組資料依「鍵值不遞減」的順序排序,總共須要7個回合,每一回合排序後之結果詳如表8.3所示。 資料結構導論 - C語言實作

  24. 8.3.3.  插入排序法(Insertion Sort) 【例1】插入排序法 • 一開始,A群={83},B群={66,55,21,88,18,88*,99}。 • 第1回合, • 將B群的第1個鍵值d[1](66)插入A群,且必須保持A群的鍵值均按「不遞減」的順序排列。 • 因此66必須放到83之前,即d[0]=66,d[1]=83, • 完成後A群={66,83}, • B群={55,21,88,18,88*,99}。 資料結構導論 - C語言實作

  25. 8.3.3.  插入排序法(Insertion Sort) 資料結構導論 - C語言實作

  26. 8.3.4.  謝耳排序法(Shell Sort) • 利用「固定間格」將部分鍵值先進行一次粗略的排序。 • 挑選一個固定的間距值s,然後將待排序的n筆鍵值分割成s組,每一群組裡的鍵值是從原始n個鍵值中挑出相間隔s間距的鍵值而成。 • 可減少插入排序法的資料搬動次數。 資料結構導論 - C語言實作

  27. 8.3.4.  謝耳排序法(Shell Sort) • 採用謝耳排序法將編號為0、1、2、...、n-1的n筆記錄按照「鍵值不遞減」的順序加以排列的步驟如下: 步驟1:將n筆記錄的鍵值儲存到陣列d[n]中,其中d[0]儲存第0號記錄的鍵值、d[1]儲存第1號記錄的鍵值、…、d[n-1]儲存第n號記錄的鍵值。 步驟2:設定一適當之s值。(最好選用質數來當作 s值) 資料結構導論 - C語言實作

  28. 8.3.4.  謝耳排序法(Shell Sort) 步驟3:分組,將陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-1]均勻地分成s組,且同一組內的陣列元素之間距均為s,分配結果如下: 令a = (n-1)/s。 第1組 = {d[0],d[s],s[2×s],...,A[a×s]}。 第2組 = {d[1],d[1+s],s[1+2×s],..., A[1+a×s]}。 第3組 = {d[2],d[2+s],s[2+2×s],...,A[2+a×s]}。 ‧‧‧ 第s組 = {d[s-1],d[2×(s-1)],s[3×(s-1)],...。 資料結構導論 - C語言實作

  29. 8.3.4.  謝耳排序法(Shell Sort) 步驟4:使用插入排序法分別針對第1組、第2組、第3組、...、第s組進行「鍵值不遞減」排序。 步驟5:重新排列,將每一組的第1個值、第2個鍵值、第3個鍵值、...重新排列到d[0]、d[1]、d[2]、…、d[n-1]位置。 步驟6:重新設定一個較小的s值。若s>0則回到步驟3。 步驟7:列印出陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-i]之值。 資料結構導論 - C語言實作

  30. 8.3.4.  謝耳排序法(Shell Sort) 【例1】謝耳排序法 • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值分別為{83,66,55,21,88,18,88*,99},並且已經儲存在一維陣列d[8]中。 • 採用「謝耳排序法」來將該組資料依「鍵值不遞減」的順序排序之過程如下: • 第1回合,我們假設s=3,將8個鍵值區分成3組。每一個組最多有3個鍵值,最少有2個鍵值。 • 第1組鍵值={d[0]、d[3]、d[6]}={83、21、88*}。 • 第2組鍵值={d[1]、d[4]、d[7]}={66、88、99}。 • 第3組鍵值={d[2]、d[5]}={55、18}。 資料結構導論 - C語言實作

  31. 8.3.4.  謝耳排序法(Shell Sort) 使用插入排序法分別對第1組、第2組、第3組鍵值進行排序,結果為: • 第1組鍵值={21、83、88*}。 • 第2組鍵值={66、88、99}。 • 第3組鍵值={18、55}。 重新排列,將每一組的第1個鍵值,分別放入d[0]、d[1]、 d[2]。將每一組的第2個鍵值,分別放入d[3]、d[4]、 d[5]。將每一組的第3個鍵值,分別放入d[6]、d[7],得到: 資料結構導論 - C語言實作

  32. 8.3.4.  謝耳排序法(Shell Sort) • 第2回合,令s=s-1=3-1=2,將8個鍵值區分成2組。 • 第1組鍵值={d[0]、d[2]、d[4]、d[6]}={21、18、88、88*}。 • 第2組鍵值={d[1]、d[3]、d[5]、d[7]}={66、83、55、99}。 使用插入排序法分別對第1組、第2組鍵值進行排序,結果為: • 第1組鍵值={18、21、88、88*}。 • 第2組鍵值={55、66、83、99}。 資料結構導論 - C語言實作

  33. 8.3.4.  謝耳排序法(Shell Sort) • 第3回合,令s=s-1=2-1=1,直接用插入排序法對陣列d的鍵值排序,得到: 資料結構導論 - C語言實作

  34. 8.3.5.  快速排序法(Quick Sort) • 採用插入排序法將編號為0、1、2、...、n-1的n筆記錄按照「鍵值不遞減」的順序加以排列的步驟如下: 步驟1:將n筆紀錄的鍵值儲存到陣列d[n]中,其中d[0]儲存第0號紀錄的鍵值、d[1]儲存第1號紀錄的鍵值、…、d[n-1]儲存第n-1號紀錄的鍵值。 步驟2:設d[low]至d[high]為本次待排序的資料範圍(low < high)。令K= d[low]。 步驟3:從左(d[low+1])向右(d[high])找出一個鍵值Ki=d[i],滿足Ki  K。(若Ki不存在,則令i=high+1)。 資料結構導論 - C語言實作

  35. 8.3.5.  快速排序法(Quick Sort) 步驟4:從右(d[high])向左(d[low])找出一個鍵值Kj=d[j],滿足Kj ≤K。(若Kj不存在,則令j=low)。 步驟5:若i < j,則將Ki 與Kj交換,然後跳到步驟2。 步驟6:若i  j則將K與Kj交換,並以j為分割點將待排序的鍵值範圍(d[low]至d[high])分割成左右兩半,即:左半邊 = {d[low]、d[low+1]、d[low+2]、...、d[j-1]}。右半邊 = {d[j+1]、d[j+2]、d[j+3]、...、d[high]}。 步驟7:再分別針對左右兩半邊遞迴地執行步驟2-6,直到low = high(即只剩下一個鍵值)為止。 步驟8:列印出陣列元素d[0]、d[1]、d[2]、d[3]、...、d[n-2]、d[n-1]之值。 資料結構導論 - C語言實作

  36. 8.3.5.  快速排序法(Quick Sort) 【例1】快速排序法 • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值{83,66,55,21,88,18,88*,99}已經儲存到一維陣列d[8]中。 • 如果我們採用「快速排序法」來將該組資料依「鍵值不遞減」的順序排序,每一回合排序處理過程詳如表8.8所示。 資料結構導論 - C語言實作

  37. 8.3.5.  快速排序法(Quick Sort) • 步驟1, • 排序範圍為d[0]至d[7],即low=0,high=7。 • K=d[0]=83,從d[0]往右(d[7])找出Ki  K,結果找到Ki=K4=d[4]=88  83。 • 從d[7]往左(d[0])找出Kj ≤ K,結果找到Kj=K5=d[5]=18 ≤ 83。 • 因i < j,將Ki 與 Kj交換(即d[4]=88與d[5]=18交換), • 得到d[4]=18,d[5]=88。結果如表8.8步驟2所示。 資料結構導論 - C語言實作

  38. 8.3.5.  快速排序法(Quick Sort) • 步驟2, • 排序範圍還是d[0]至d[7],即low=0,high=7。 • K=d[0]=83,從d[0]往右(d[7])找出Ki  K,結果找到Ki=K5=d[5]=88  83。 • 從d[7]往左(d[0])找出Kj ≤ K,結果找到Kj=K4=d[4]=18 ≤ 83。 • 因i > j,將K 與 Kj交換(即d[0]=83與d[4]=18交換), • 得到d[0]=18,d[4]=83。結果如表8.8步驟3所示。 資料結構導論 - C語言實作

  39. 8.3.5.  快速排序法(Quick Sort) • 步驟3, • 以d[j]=d[4]=83為分割點,將待排序的資料範圍分割成左半邊(即d[0]到d[3])和右半邊(即d[5]到d[7]), • 結果如表8.8步驟3所示。 • 其餘詳細步驟,請參閱課本表8.8 資料結構導論 - C語言實作

  40. 8.3.5.  快速排序法(Quick Sort) 資料結構導論 - C語言實作

  41. 8.3.6.  樹排序法 (Tree Sort) • 二元搜尋樹(Binary Search Tree) • 二元搜尋樹中的任一節點其左子樹的節點鍵值一定比它小 • 其右子樹的節點鍵值一定大於或等於它 資料結構導論 - C語言實作

  42. 8.3.6.  樹排序法 (Tree Sort) • 採用樹排序法將編號為0、1、2、...、n-1的n筆記錄按照「鍵值不遞減」的順序加以排列的步驟如下: 步驟1:輸入n筆鍵值,以鍵值為樹的節點來建造一棵二元搜尋樹。即:以第1個輸入的鍵值為樹根。對於第2個鍵值到第n個鍵值執行下列動作:a.  從樹根開始比較大小,若比樹根小 則往左子樹繼續比較,否則往右子 樹繼續比較。b.  當遇到樹葉節點,若比樹葉節點小 則放在左子樹,否則放在右子樹。 步驟2:以中序法追蹤所得即為按鍵值不遞減之排序結果。 資料結構導論 - C語言實作

  43. 8.3.6.  樹排序法 (Tree Sort) 【例1】樹排序法(Tree Sort) • 假設有一組未經排序的資料R0、R1、R2、...、R7,其鍵值為:{83,66,55,21,88,18,88*,99}。 • 步驟1,輸入鍵值{83,66,55,21,88,18,88*,99},並建造出一棵二元搜尋樹。 資料結構導論 - C語言實作

  44. 8.3.6.  樹排序法 (Tree Sort) 資料結構導論 - C語言實作

  45. 8.3.6.  樹排序法 (Tree Sort) • 步驟2,用中序法追蹤二元搜尋樹即可得到按鍵值不遞減之排序結果,即: 18、21、55、66、83、88、88*、99 資料結構導論 - C語言實作

  46. 8.3.7.  堆積排序法(Heap Sort) • 完整二元樹須滿足以下條件: • 完整二元樹是一棵二元樹。 • 完整二元樹的建立須先有左子樹然後才有右子樹。 • 完整二元樹的樹葉節點,頂多相差1個階度。 資料結構導論 - C語言實作

  47. 8.3.7.  堆積排序法(Heap Sort) • 圖8.7即是一個含有8個節點的完整二元樹 • 其中0、1、2、3、...、7為節點之編號,也是建造完整二元樹的順序,而 • K0、K1、K2、K3、...、K7為樹中節點所儲存之鍵值。 資料結構導論 - C語言實作

  48. 8.3.7.  堆積排序法(Heap Sort) • 堆積樹須滿足以下條件: • 是一棵完整二元樹(或完滿二元樹)。 • 每一個節點之鍵值大於或等於其子節點之鍵值。 資料結構導論 - C語言實作

  49. 8.3.7.  堆積排序法(Heap Sort) • 採用堆積排序法將編號為0、1、2、...、n-1的n筆記錄之鍵值{K0,K1,K2,…,Kn-1},按照「鍵值不遞增」的順序加以排列的步驟如下: 步驟1:以鍵值{K0,K1,K2,…,Kn-1}建造出完整二元樹(如圖8.7之結構),如果用陣列d[n]來儲存完整二元樹,則d[0]=K0,d[1]=K1,d[2]=K2,d[3]=K3,...,A[n-1]=Kn-1。 步驟2:將完整二元樹轉換成對應的堆積樹。 步驟3:將樹根砍下來並輸出樹根之鍵值。 資料結構導論 - C語言實作

  50. 8.3.7.  堆積排序法(Heap Sort) 步驟4:將堆積樹的最後一個節點(即編號最大的節點)搬到樹根位置成為新的樹根節點。 步驟5:如果只剩樹根節點則輸出樹根之鍵值,結束。否則,重建堆積樹,然後回到步驟3。 資料結構導論 - C語言實作

More Related