1. 程式人生 > >怎麽排序超大文件

怎麽排序超大文件

數據 階段 臨時文件 效果 產生 輸入緩沖 內存大小 小堆 開始

外排序

通常來說,外排序處理的數據不能一次裝入內存,只能放在讀寫較慢的外存儲器(通常是硬盤)上。外排序通常采用的是一種“排序-歸並”的策略。在排序階段,先讀入能放在內存中的數據量,將其排序輸出到一個臨時文件,依此進行,將待排序數據組織為多個有序的臨時文件。之後在歸並階段將這些臨時文件組合為一個大的有序文件,也即排序結果。

外排序的一個例子是外歸並排序(External merge sort),它讀入一些能放在內存內的數據量,在內存中排序後輸出為一個順串(即是內部數據有序的臨時文件),處理完所有的數據後再進行歸並。[1][2]比如,要對900 MB的數據進行排序,但機器上只有100 MB的可用內存時,外歸並排序按如下方法操作:

讀入100 MB的數據至內存中,用某種常規方式(如快速排序、堆排序、歸並排序等方法)在內存中完成排序。
將排序完成的數據寫入磁盤。
重復步驟1和2直到所有的數據都存入了不同的100 MB的塊(臨時文件)中。在這個例子中,有900 MB數據,單個臨時文件大小為100 MB,所以會產生9個臨時文件。
讀入每個臨時文件(順串)的前10 MB( = 100 MB / (9塊 + 1))的數據放入內存中的輸入緩沖區,最後的10 MB作為輸出緩沖區。(實踐中,將輸入緩沖適當調小,而適當增大輸出緩沖區能獲得更好的效果。)
執行九路歸並算法,將結果輸出到輸出緩沖區。一旦輸出緩沖區滿,將緩沖區中的數據寫出至目標文件,清空緩沖區。一旦9個輸入緩沖區中的一個變空,就從這個緩沖區關聯的文件,讀入下一個10M數據,除非這個文件已讀完。這是“外歸並排序”能在主存外完成排序的關鍵步驟 -- 因為“歸並算法”(merge algorithm)對每一個大塊只是順序地做一輪訪問(進行歸並),每個大塊不用完全載入主存。

為了增加每一個有序的臨時文件的長度,可以采用置換選擇排序(Replacement selection sorting)。它可以產生大於內存大小的順串。具體方法是在內存中使用一個最小堆進行排序,設該最小堆的大小為 {\displaystyle M} M。算法描述如下:

初始時將輸入文件讀入內存,建立最小堆。
將堆頂元素輸出至輸出緩沖區。然後讀入下一個記錄:
若該元素的關鍵碼值不小於剛輸出的關鍵碼值,將其作為堆頂元素並調整堆,使之滿足堆的性質;
否則將新元素放入堆底位置,將堆的大小減1。
重復第2步,直至堆大小變為0。
此時一個順串已經產生。將堆中的所有元素建堆,開始生成下一個順串。[3]
此方法能生成平均長度為 {\displaystyle 2M} 2M的順串,可以進一步減少訪問外部存儲器的次數,節約時間,提高算法效率。

怎麽排序超大文件