海量數據排序


今天要給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億個數字排序?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM