假设我有可用的X GB RAM空间,我需要对大量数据进行排序(所有可用内存都要大得多。它存储在硬盘上)。你能否提一下,如何实现?
答案 0 :(得分:15)
您正在寻找外部排序。 这些方案中最大的成本通常是磁盘IO。因此,诀窍是使用最小化磁盘IO的算法。 通常的方法是将大块内容读入内存,对这些块进行排序,将它们保存回磁盘,然后合并排序后的块。
搜索“外部排序”或“排序合并”以及您选择的技术应该会给出一些好的结果。
答案 1 :(得分:8)
让我们假设您有一个巨大的文件H并限制内存M.
我有两个解决方案。
解决方案1:
步骤1:从文件中读取M并将其写入临时缓冲区
第2步:排序(您应该使用就地排序算法,如QuickSort,HeapSort)值
步骤3:创建临时文件并将缓冲区写入临时文件。保存临时文件的名称
步骤4:重复步骤1到3,直到读取文件H out,然后将M out排序并保存所有临时文件
步骤5:将所有临时文件合并到新文件。创建一个新文件,打开所有临时文件,将文件句柄放入数组中
步骤6:从文件读指针当前指向的数字集中查找最小数字。您可以使用常规方法来执行此操作,比较每个数字,并使用临时变量来记住它(时间复杂度为O(n)。或者您可以创建priorityQueue和地图,地图的关键是数字,并且map的值是文件句柄的序列。(时间复杂度是O(lgn),第二种方式浪费更多内存,但性能更好,如果你想要更好的方法,你可以使用int来替换列表使用位图,因为临时文件名被隔离
步骤7:将号码保存到新文件中
步骤8:在步骤6中从包含最小数字的文件中读取另一个数字
步骤9:重复步骤7到8,直到处理完所有临时文件中的所有数字。
解决方案2:
步骤1:创建N个临时文件,每个临时文件的编号范围不同。(例如,temp_file_1的范围是0到1000000,下一个临时文件是1000001到2000000 ......) />
步骤2:从H文件中读取m并将数字写入不同的临时文件,直到没有任何内容可以从文件H中读取
第3步:对每个临时文件进行排序
步骤4:创建一个新文件,将所有临时文件逐个合并到这个新文件中。
解决方案之间有什么区别。 根据解决方案1,每个数字被排序一次并且被多次比较(步骤5),但是只读取和写入两次。关于解决方案2,没有合并处理,但每个数字都被读取并写入三次。
答案 2 :(得分:5)
您正在寻找的是外部排序。
答案 3 :(得分:2)
实际上,如果您不想编写太多代码,并且磁盘使用不是问题,请将数据放入具有适当索引的数据库中,然后从那里开始select * order by
。
答案 4 :(得分:0)
我想你可能构建某种索引系统,你可以将你的分类数据分成。
想象一下图书馆的书架。遍历1 / x数据,将所有元素排序到隔离专区,并将每个隔离专区缓存到磁盘上的单个文件。然后对下一个1 / x数据进行排序,将其写回磁盘,等等。一旦你把所有数据都放在架子上,然后分别对每个架子进行排序,最后将它们合并到一个很好的分类文件中。
答案 5 :(得分:0)
您可以使用ZZZServer对许多大文件(排序结果可以是太字节和更大)进行排序,它可以免费用于非商业用途:
zbar
排序后,结果保存在
中ZZZServer -sortinit -sort file1.txt
ZZZServer -sort file2.txt
ZZZServer -sort file3.txt
...
ZZZServer -sortsave sorted.txt
您的输入文件必须以UTF-8或ASCII格式编码!
ZZZServer在分拣大文件时使用大约1MB RAM!