【问题标题】:Sorting Data with Space Contrainsts使用空间约束对数据进行排序
【发布时间】:2015-04-07 14:52:57
【问题描述】:

现在问题很简单。您有 1000 MB,您必须对其进行排序。现在的问题是您只有 100 MB 的空间来对数据进行排序。 (假设 1000 MB 存储在磁盘中,而您只有 100 MB 的 RAM 来对数据进行排序。-任何时候,您的 RAM 中只能有 100 MB 的数据。)

现在我想出了这个解决方案:

  1. 将数据分成 10 部分 - 每部分 100 MB,然后使用快速排序对其进行排序。
  2. 然后将所有数据块写入硬盘。
  3. 现在从每个块中选择前 10 MB,然后合并。现在你有 100 MB。现在将这 100 MB 分开。
  4. 现在做同样的事情。从每个块中选择接下来的 10 MB 并合并。
  5. 继续这样做,然后连接数据。

现在我面临的问题是,每次连接时我们都会单独合并 100 MB,我们会出错。 (这 100 MB 也应该合并在一起。)

我该如何解决这个问题?

【问题讨论】:

  • 您不必从头开始设计该算法,它称为外部排序,特别是您可能需要合并排序
  • 我知道归并排序,但它是如何工作的?因为在合并排序中,您需要 1000 MB 的空间来将所有数据重新合并在一起。另外我不知道什么是外部排序?
  • 将子块视为一种排序流。您同时打开了所有n 子流,并从任何n 子流中选择最小的元素。外部归并排序与内部归并排序略有不同。不要混淆。

标签: sorting


【解决方案1】:

外部合并排序在合并阶段与内部版本不同。在您的问题中,您尝试将内部合并算法直接应用于外部合并。

因此,您最终不得不合并两个大小为n / 2 的块。正如您正确指出的那样,这是行不通的,因为您的内存不足。

假设您有足够的内存对所有元素中的1/k 进行排序。这将为您留下k 排序列表。您无需合并两个列表,而是一次合并所有 k

  1. 选择一个输出缓冲区大小。一个不错的价值似乎是n / 2。这会为每个子块留下 n / 2 内存用于输入缓冲或 m = n / (2 x k)
  2. 从每个子块中读取第一个m 元素。现在所有内存都已使用,并且您在内存中的每个子块中拥有最低的 m 元素。
  3. 从每个k 输入缓冲区中,选择最小值。将此值附加到输出缓冲区中。重复直到您的输入缓冲区之一用完。
  4. 如果您的输入缓冲区之一用完,请从磁盘上的子块中读取下一个 m 元素。如果没有更多元素,您就完成了子块。
  5. 如果输出缓冲区已满,请将其附加到输出文件并将其位置重置为开头。
  6. 冲洗并从 (3) 开始重复,直到所有子块用完。

现在输出文件已排序。

您可以将输入缓冲区视为已排序存储桶上的一组流式缓冲区。检查流并从所有流中选择最佳(即最低)元素并将其保存到输出列表中。从外部看,它是一个带有智能预取和输出缓冲的流合并。

【讨论】:

    【解决方案2】:

    您需要重复步骤 3 和 4。N-1 次。

    【讨论】:

    • 我确实明白了,但问题是连接数据不会对其进行排序。例如,您有一个数据集 1,2,3,4,5 和另一个数据集 3,4,5,6。连接它会得到 1,2,3,4,5,3,4,5,6。但最终的解决方案没有排序。你明白我的意思还是我错过了什么?
    • 我想我不清楚重复步骤 3 和 4 的意思。让我举个例子。假设这 2 个排序集有 1,2,3,4,5 和 2,3,4,5,6。循环 1> 1,2,3,4,5 ::: 2,3,4,5,6。 //获取排序列表的前 10mb 循环 2> 1223 :::: 3445 :::: 56
    猜你喜欢
    • 2023-04-10
    • 2021-04-26
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 2014-06-28
    相关资源
    最近更新 更多