【问题标题】:How to actually use merge sort for large data sets如何对大型数据集实际使用归并排序
【发布时间】:2016-09-04 20:17:09
【问题描述】:

如何对大型数据集实际使用归并排序?

假设我有几个带有以下数据的排序文件:

1.txt

1
2
2

2.txt

3
4
5

3.txt

1
1
1

假设我们不能同时将所有文件的内容保存在内存中(假设我们只能保存每个文件中的两个数字)。

我听说在这种情况下我可以使用某种 R-way 合并排序,但我不明白我该怎么做。

如您所见,第一次迭代将为我们提供以下排序序列:

1 1 1 2 3 4

,所以我们将它刷新到输出文件。但是,我们将在下一次迭代中再次获得1(来自3.txt 文件),因此整个结果序列是错误的!

【问题讨论】:

  • 只要您(可能)从其中一个文件中得到 1,就不要移动到 2?

标签: algorithm sorting mergesort external-sorting


【解决方案1】:

I heard that I can use some kind of R-way merge sort in this case but I don't understand how can I actually do it.

N 路合并很容易解释。您打开所有文件,从每个文件中获取第一个元素并将它们放入堆中。 然后,该算法通过从堆(pop)中获取最小元素,将其写入输出缓冲区,然后从该项目所源自的文件中读取下一个元素。重复直到所有文件都为空。

【讨论】:

  • 所以,重点是在每一步中获取最小的元素?如果有,有什么办法可以优化吗?
  • @rcgldr 好主意,但瓶颈通常在磁盘 IO 上,而不是在 CPU 排序上。
  • @ThomasJungblut - 删除了我之前的评论,稍后会删除。我建议对于 3 或 4 个文件,可以使用更简单(而不是更快)的方法。
  • @FrozenHeart - 正如 ThomasJungblut 所指出的那样 - 该过程通常是磁盘 I/O 绑定的,因此堆是实现 R-way 合并的常用方法(通常这称为 k-way合并)。除了要排序的元素之外,堆还需要包含文件信息(哪个文件,...)。
【解决方案2】:

首先填充与文件一样多的变量,一个变量附加到一个文件。在每一步中找到三个变量中的最小值,并将其刷新到输出,同时从同一个文件中再次填充。

| 1.txt | 2.txt | 3.txt |
| 1     | 3     | 1     | output 1 refill from file 1
| 2     | 3     | 1     | output 1 refill from file 3
| 2     | 3     | 1     | output 1 refill from file 3
| 2     | 3     | 1     | output 1 refill from file 3
| 2     | 3     | nil   | output 2 refill from file 1
| 2     | 3     | nil   | output 2 refill from file 1
| nil   | 3     | nil   | output 3 refill from file 2
| nil   | 4     | nil   | output 4 refill from file 2
| nil   | 5     | nil   | output 5 refill from file 2
| nil   | nil   | nil   | end

【讨论】:

  • 所以,重点是在每一步中获取最小的元素?如果有,有什么办法可以优化吗?
  • @FrozenHeart 可能不是很有用,输出成本远高于比较三个元素。
猜你喜欢
  • 1970-01-01
  • 2018-02-08
  • 2016-03-11
  • 1970-01-01
  • 2014-12-11
  • 2017-02-22
  • 1970-01-01
  • 2017-08-24
相关资源
最近更新 更多