今天要給100億個數字排序,100億個 int 型數字放在檔案裡面大概有 37.2gb,非常大,記憶體一次裝不下了。那麼肯定是要拆分成小的檔案乙個乙個來處理,最終在合併成乙個排好序的大檔案。
實現思路
1.把這個37gb的大檔案,用雜湊分成1000個小檔案,每個小檔案平均38mb左右(理想情況),把100億個數字對1000取模,模出來的結果在0到999之間,每個結果對應乙個檔案,所以我這裡取的雜湊函式是 h = x % 1000,雜湊函式取得"好",能使衝突減小,結果分布均勻。
2.拆分完了之後,得到一些幾十mb的小檔案,那麼就可以放進記憶體裡排序了,可以用快速排序,歸併排序,堆排序等等。
3.1000個小檔案內部排好序之後,就要把這些內部有序的小檔案,合併成乙個大的檔案,可以用二叉堆來做1000路合併的操作,每個小檔案是一路,合併後的大檔案仍然有序。
首先遍歷1000個檔案,每個檔案裡面取第乙個數字,組成 (數字, 檔案號) 這樣的組合加入到堆裡(假設是從小到大排序,用小頂堆),遍歷完後堆裡有1000個 (數字,檔案號) 這樣的元素
然後不斷從堆頂拿元素出來,每拿出乙個元素,把它的檔案號讀取出來,然後去對應的檔案裡,加乙個元素進入堆,直到那個檔案被讀取完。拿出來的元素當然追加到最終結果的檔案裡。
按照上面的操作,直到堆被取空了,此時最終結果檔案裡的全部數字就是有序的了。
最後我用c++寫了個實驗程式,具體**在這裡可以看到。
更新:不用對數字進行雜湊,直接平均分成1000份,進行內部排序後,直接進行 k 路歸併排序,也是可以的。
思維拓展
類似的100億個數字求和,求中位數,求平均數,套路就是一樣的了。
求和:統計每個小檔案的和,返回給master再求和就可以了。
求平均數:上面能求和了,再除以100億就是平均數了
求中位數:在排序的基礎上,遍歷到中間的那個數就是中位數了。
--引用:如何給100億個數字排序?
海量資料排序
海量資料排序 2011 04 12 19 33 1億資料找出最大的1w個 1.分塊法 解法 a.採用分塊法,將1億資料分成100w一塊,共100塊。b.對每塊進行快速排序,分成兩堆,如果大堆大於1w個,則對大堆再次進行快速排序,直到小於等於1w停止 假設此時大堆有n個 此時對小堆進行排序,取最大的1...
海量資料排序演算法
題目 有100萬無序資料,要求從小到大排序。但是每次記憶體只能排序1萬條資料。1.因為每次只能處理1萬條資料,所以要分組處理,我們將100萬資料分成100組 2.因為每組資料都是無序的,所以我們使用平均時間複雜度較好的演算法。3.當我們分組排序完成後,我們要排序1萬條資料就會簡單很多了。我們一共要取...
海量資料處理 排序問題
乙個檔案中有9億條不重複的9位整數,對這個檔案中數字進行排序 針對這個問題,最容易想到的方法是將所有資料匯入到記憶體中,然後使用常規的排序方法,例如插入排序,快速排序,歸併排序等各種排序方法對資料進行排序,最後將排序好的資料存入檔案.但這些方法在此並不適用,由於資料量巨大,對32位機器而言,很難將這...