Algorithm 具有大量整数的合并排序

Algorithm 具有大量整数的合并排序,algorithm,sorting,Algorithm,Sorting,需要对大量无法保存在内存中的整数进行排序。想知道合并排序是否正确吗?我的解决方案是这样的 对每5%的整数使用基于内存的排序,这可以保存在内存中,使用快速排序可以在内存中高效执行 在对每20个块进行排序后,使用merge sort对20个列表进行排序,对于merge sort,我只需要将每个文件的一部分加载到内存中,如果同一列表的当前部分已完全排序为最终结果,则加载同一列表的下一部分。因为20个列表中的每一个都是排序的,我只需要从头到尾顺序加载部分块,所以内存是可以承受的 我不确定这是否是进行大量

需要对大量无法保存在内存中的整数进行排序。想知道合并排序是否正确吗?我的解决方案是这样的

  • 对每5%的整数使用基于内存的排序,这可以保存在内存中,使用快速排序可以在内存中高效执行
  • 在对每20个块进行排序后,使用merge sort对20个列表进行排序,对于merge sort,我只需要将每个文件的一部分加载到内存中,如果同一列表的当前部分已完全排序为最终结果,则加载同一列表的下一部分。因为20个列表中的每一个都是排序的,我只需要从头到尾顺序加载部分块,所以内存是可以承受的
  • 我不确定这是否是进行大量整数排序的正确方法?

    GNU排序程序(与它的Unix前身一样)使用内存排序,然后根据需要进行多达16路的合并。请参阅此处的代码以了解更多信息:

    自从

    它们是整数,大多数是1-100

    你所需要的就是


    它的实现非常简单

  • 创建一个包含100个整数(或
    HashMap
    )的数组,名为
    intCounts
    (如果您认为32位可能溢出,则使用64位整数)
  • 逐个读取要排序的整数
  • 对于每个要排序的
    inputInteger
    ,只需执行
    intCounts[inputInteger]+
  • 读取所有整数后,
    intCounts[i]
    告诉您在大整数集中看到integer
    i
    的次数
  • 只需在
    intCounts
    上迭代,从最小索引到最高索引
  • 写回
    i
    总共
    intCounts[i]
  • 现在您已经写回了所有输入整数的排序列表

  • 可能需要研究的是外部排序是的,这是正确的方法。我已经用过很多次了。除了我多次执行双向合并,而不是20路合并。是的,您描述的正是外部合并排序算法。我不确定20路是否会更快。对数据进行的传递更少,但比较过程要复杂得多。根据你们得到的答案,我猜有人已经研究过这个问题,并认为16路是最佳的,但我不能证实这一点。它们是什么类型的整数?常规32位整数?感谢cliffordheath,对于16路合并,它们是否使用基于外部存储的合并排序?16路或任何k路排序通常是合并排序,在本例中是外部合并排序@LinMa-取决于合并过程的数量是否通过变大k而减少。一旦你有了可以处理k-way合并的代码,较大的k不会使它变得更复杂,但是即使是基本的k-way合并也是复杂的,因为当到达一个运行的末尾时,它是k-1路合并,然后是k-2路合并,然后只剩下一个运行的剩余部分,然后被复制。要使k>2有效,需要大I/O以减少随机访问开销(假设您没有2 x k设备或使用SSD驱动器进行排序)。@Lin:我指向代码,这样您就可以读取它了!是的,他们使用临时文件。每个N向合并排序产生一个文件-因此,如果您有M个文件要开始,则所需的合并数量按照log-to-base-N(M)的顺序进行。所以N越大,N的数量就越少merges@LinMa-为了跟进cliffordheath的评论,示例代码的初始过程创建了M个临时排序文件,其中M=(文件大小)/(有效缓冲区大小)。使用单个文件和M个文件指针是另一种选择,但我猜在编写示例时,文件指针是32位的。Linux和Windows现在都有用于fseek()和ftell()的64位备选方案。displayName、smart和smart.:)@琳玛:没什么聪明的。我只是被告知。现在,你也是。希望你能随时帮我通知我。我很想向你学习。:)