設想有一個20GB的文件,每一行一個字符串。說明如何將這個文件進行排序。

設想有一個20GB的文件,每一行一個字符串。說明如何將這個文件進行排序。php

 

思路1:外部排序,將部分數據載入內存。算法

將整個文件劃分紅許多塊,每一個塊xMB,其中x是可用的內存大小。每一個塊各自進行排序,而後存迴文件系統。各個塊一旦完成排序,便將這些塊逐一合併在一塊兒,最終就能獲得所有排好序的文件。排序

 

思路2:ip

內存確定沒有20GB大,因此不可能採用傳統排序法。可是能夠將文件分紅許多塊,每塊xMB,針對每一個塊各自進行排序,存迴文件系統。內存

而後將這些塊逐一合併,最終獲得所有排好序的文件。ci

 

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

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