外部排序

學習一個知識的步驟:

  1. 什麼是外部排序? What?
  2. 爲什麼要使用外部排序? Why?
  3. 怎樣使用外部排序? How?

1.什麼是外部排序?

外部排序指的是大文件的排序,即待排序的記錄存儲在外存儲器上,待排序的文件無法一次裝入內存,需要在內存和外部存儲器之間進行多次數據交換,以達到排序整個文件的目的。


2. 爲什麼要使用外部排序?

文件數據量太大,而內存無法滿足其需要。


3. 怎樣使用外部排序?

一般情況下外部排序分爲兩個步驟:預處理和合並排序。
常用的解決方法就是多路歸併排序算法。

處理過程
1.按可用內存的大小,把外存上含有n個記錄的文件分成若干個長度爲L的子文件,把這些子文件依次讀入內存,並利用有效的內部排序方法對它們進行排序,再將排序後得到的有序子文件重新寫入外存。

2.對這些有序子文件逐趟歸併,使其逐漸由小到大,直至得到整個有序文件爲止。

舉例說明:
假設有一個含1000G記錄的文件,但是內存只有100G大小,首先通過10 次內部排序得到10 個初始歸併段R1~R10 ,其中每一段都含100G 個記錄。然後對它們作如圖所示的兩兩歸併,直至得到一個有序文件爲止:
這裏寫圖片描述

接下來說一下·多路歸併排序算法:
過程大致爲:
1):首先將k個歸併段中的首元素關鍵字依次存入b[0]–b[k-1]的葉子結點空間裏,然後調用CreateLoserTree創建敗者樹,創建完畢之後最小的關鍵字下標(即所在歸併段的序號)便被存入ls[0]中。然後不斷循環:

2)把ls[0]所存最小關鍵字來自於哪個歸併段的序號得到爲q,將該歸併段的首元素輸出到有序歸併段裏,然後把下一個元素關鍵字放入上一個元素本來所 在的葉子結點b[q]中,調用Adjust順着b[q]這個葉子結點往上調整敗者樹直到新的最小的關鍵字被選出來,其下標同樣存在ls[0]中。循環這個 操作過程直至所有元素被寫到有序歸併段裏。
這裏寫圖片描述

這裏寫圖片描述

多路歸併排序算法、從2路到多路(k路),增大k可以減少外存信息讀寫時間,但k個歸併段中選取最小的記錄需要比較k-1次, 爲得到u個記錄的一個有序段共需要(u-1)(k-1)次,若歸併趟數爲s次,那麼對n個記錄的文件進行外排時,內部歸併過程中進行的總的比較次數爲 s(n-1)(k-1),也即(向上取整)(logkm)(k-1)(n-1)=(向上取整)(log2m/log2k)(k-1)(n-1),而(k- 1)/log2k隨k增而增因此內部歸併時間隨k增長而增長了,抵消了外存讀寫減少的時間,這樣做不行,由此引出了“敗者樹”tree of loser的使用。

敗者樹是完全二叉樹, 因此數據結構可以採用一維數組。其元素個數爲k個葉子結點、k-1個比較結點、1個冠軍結點共2k個。ls[0]爲冠軍結點,ls[1]–ls[k- 1]爲比較結點,ls[k]–ls[2k-1]爲葉子結點(同時用另外一個指針索引b[0]–b[k-1]指向)。另外bk爲一個附加的輔助空間,不屬於敗者樹,初始化時存着MINKEY的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章