1. 程式人生 > >點陣圖排序、多路歸併排序-應對磁碟檔案排序

點陣圖排序、多路歸併排序-應對磁碟檔案排序

注意

點陣圖排序的程式效率是最快的,約為14s,而採用上述的多路歸併演算法的程式執行時間約為25s。時間主要浪費在讀寫磁碟IO上,且程式中用的庫函式qsort也耗費了不少時間。所以,總的來說,採取點陣圖方案是最佳方案。

歸併排序和快速排序比較:

歸併排序的最大特點是,它是一種穩定的排序方法。
歸併排序一般多用於外排序。
歸併排序在內排方面也佔有重要地位,因為它是基於比較的時間複雜度為O(N*Log(N))的排序演算法中唯一穩定的排序,所以在需要穩定內排序時通常會選擇歸併排序。
歸併排序不要求對序列可以很快地進行隨機訪問,所以在連結串列排序的實現中很受歡迎。

二路歸併排序:

過程的核心操作是將一維陣列中相鄰的兩個有序表歸併為一個有序表

多路歸併排序:

當資料量大到不適合在記憶體中排序時,多路歸併演算法對磁碟檔案進行排序。

如何給磁碟檔案排序

問題描述:

輸入:給定一個檔案,裡面最多含有n個不重複的正整數(也就是說可能含有少於n個不重複正整數),且其中每個數都小於等於n,n=10^7。
輸出:得到按從小到大升序排列的包含所有輸入的整數的列表。
條件:最多有大約1MB的記憶體空間可用,但磁碟空間足夠。且要求執行時間在5分鐘以下,10秒為最佳結果。

分析檔案大小:

10^7 = 1000,0000 = 10,000,000
一個數據=1B,那麼大約為10M

歸併排序(二路歸併排序):

你可能會想到把磁碟檔案進行歸併排序,但題目要求你只有1MB的記憶體空間可用,所以,歸併排序這個方法不行。

點陣圖排序:

用一個20位長的字串來表示一個所有元素都小於20的簡單的非負整數集合?

{1,2,3,5,8,13}:0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0
上述集合中各數對應的位置則置1,沒有對應的數的位置則置0

適用範圍:

針對不重複的資料進行排序

點陣圖排序需要空間大小計算

第一次,只處理1—4999999之間的資料,這些數都是小於5000000的,對這些數進行點陣圖排序,只需要約5000000/8=625000Byte,也就是0.625M,排序後輸出。
第二次,掃描輸入檔案時,只處理4999999-10000000的資料項,也只需要0.625M(可以使用第一次處理申請的記憶體)。
因此,總共也只需要0.625M

外排序(快速排序+多路歸併排序):

記憶體中快速排序

  1. 由於要求的可用記憶體為1MB,那麼每次可以在記憶體中對250K的資料進行排序,然後將有序的數寫入硬碟。
  2. 那麼10M的資料需要迴圈40次,最終產生40個有序的檔案。

多路歸併排序

  1. 將每個檔案最開始的數讀入(由於有序,所以為該檔案最小數),存放在一個大小為40的first_data陣列中;
  2. 選擇first_data陣列中最小的數min_data,及其對應的檔案索引index;
  3. 將first_data陣列中最小的數寫入檔案result,然後更新陣列first_data(根據index讀取該檔案下一個數代替min_data);
  4. 判斷是否所有資料都讀取完畢,否則返回2。

多路歸併程式的流程圖:

第一步、Memory Sort。
這裡寫圖片描述
第二步、Merge Sort。
這裡寫圖片描述