排序有限的内存

时间:2010-12-05 09:05:28

标签: memory sorting

假设我有可用的X GB RAM空间,我需要对大量数据进行排序(所有可用内存都要大得多。它存储在硬盘上)。你能否提一下,如何实现?

6 个答案:

答案 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)

您正在寻找的是外部排序。

http://en.wikipedia.org/wiki/External_sorting

答案 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!