【问题标题】:Time Complexity/Cost of External Merge Sort外部合并排序的时间复杂度/成本
【发布时间】:2012-05-08 17:37:59
【问题描述】:

我从link 那里得到这个,它谈论外部合并排序。

从幻灯片 6 示例:使用 5 个缓冲页面,对 108 个页面文件进行排序

  • Pass0:[108/5] = 22 次排序运行,每次运行 5 页(最后一次运行只有 3 页)

  • Pass1 [22/4] = 6 次排序运行,每次运行 20 页(最后运行仅 8 页)

  • Pass2:[6/3] = 2 次排序运行,80 页和 28 页

  • 通过 3:[2/2] = 1 个 108 页的已排序文件

问题:我的理解是在外部合并排序中,通过 0 创建块,然后对每个块进行排序。在剩余的通行证中,您不断合并它们。 因此,将其应用于上面的示例,因为我们只有 5 个缓冲页面,在 Pass 0 中我们需要 22 次排序运行,每次运行 5 个页面。

  1. 现在,为什么我们要对剩余的通行证进行排序运行而不是合并?

  2. 当我们只有 5 个缓冲页时,它为什么会告诉第 1、6 次排序运行,每次运行 20 页?

  3. 合并到底发生在哪里?以及 N 在每次通过时如何减少,即从 108 到 22 到 6 到 2?

【问题讨论】:

    标签: algorithm mergesort


    【解决方案1】:

    当您无法将所有数据存储到内存中时,必须使用外部合并排序。您可以做的最好的事情是将数据分解为排序的运行,然后在后续传递中合并运行。运行的长度与您的可用缓冲区大小相关。

    Pass0:您正在原地执行操作。因此,您将 5 页数据加载到缓冲区中,然后使用就地排序算法对其进行就地排序。 这 5 个页面将作为一个运行存储在一起。

    以下步骤:您无法再进行原地操作,因为您正在合并许多页面的运行。 4 个页面被加载到缓冲区中,第 5 个是写缓冲区。合并与合并排序算法相同,但您将分治系数 B-1 而不是 2。当写缓冲区被填满时,它被写入磁盘并开始下一页。

    复杂性: 在分析外部归并排序的复杂性时,要考虑的就是 I/O 的数量。在每次传递中,您必须读取一页并写入该页。设 N 为页数。每次运行将花费 2N。读一页,写一页。
    设 B 是您可以容纳缓冲区空间的页数,N 是页数。
    将有 ceil(log_B-1(ceil(N/B))) 通行证。每个通道将有 2N 个 I/O。所以 O(nlogn)。

    在每次遍历中,运行的页面长度会增加 B-1 倍,排序运行的数量会减少 B-1 倍。
    Pass0:ceil(108 / 5) = 22,每次运行 5 页
    Pass1:ceil(22 / 4) = 6,每次运行 20 页
    Pass2:ceil(6 / 4) = 2,每次运行 80 页
    Pass3: ceil(2 / 4 ) = 1 - 完成,108 页的 1 次运行

    【讨论】:

    • 假设所有页面的大小是相等的。您从 108 页加载 4 页并将其存储在 4 个输入缓冲区页面中,然后将数据合并到结果缓冲区中。现在,结果缓冲区如何保存 4 个输入缓冲区页面大小的数据?
    • 所有页面大小相同,除了最后一个。在 pass 0 中,您加载 5 个页面并就地排序。它一次不能容纳所有 4 页。它只保存每次运行的第一页,将每次运行视为一个链表。在每一页的末尾都有一个指针,指向运行中下一页的位置。数据已排序,因此第 2 页上的数据将在逻辑上位于第 1 页上的数据之后。我认为您混淆了页面和运行的含义。运行由几个页面组成,页面包含数据。
    • 对于 Pass 1,您将 4 个页面从磁盘复制到 RAM 中的 4 个输入页面,然后将这些页面合并到 RAM 中的输出页面。该输出页面是其他输入页面大小的 4 倍吗?你明白我想说什么了吗?
    • 哦,好的。嗯,是。输入和输出是 1 对 1,所以如果你读入 108 个页面,就会有 108 个页面被写入磁盘。但是每次运行的页数随着每次通过而增加。您将 1 页写入 ram,当它填满时,您将其写入磁盘。然后它清空并再次填充,填充后它会在上一页之后写入磁盘。如果缓冲区可以容纳 250 个#s,那么 200 将来自 4 个页面,一旦将 50 个排序后的数字写入输出缓冲区,就会将其保存到磁盘并清除。每当输入缓冲区的数字用完时,就会读入下一页。希望这会有所帮助。
    • 在这种奇怪的情况下,页面数量非常少,因此它是离散的,您可以通过合并 pass1 和 pass2 之间的三个 20page 运行来减少合并工作。然后 pass2 将是一个单一的 4 路合并。这减少了数据移动的总量。在实际情况下,有数千到数百万个内存页面可用,您理想的合并宽度可能会受到页面数量以外的其他因素的限制。 (例如,避免过多的 I/O 搜索)
    【解决方案2】:

    A.由于它从不提及合并,我假设(希望)后面的“排序”通道正在进行合并。

    B.同样,假设这是合并,您需要一个缓冲区来保存合并的记录,并为每个要合并的文件使用剩余的缓冲区之一:因此,4 个输入文件,每个 5 页:20 页。

    C.想我已经回答了现在合并两次的地方:)

    【讨论】:

    • 我没有看到 4 个输入文件来自哪里?您正在处理此处的页面。我可以使用 5 个缓冲页面中的 4 个来加载 108 个页面中的 4 个页面并将结果存储在最后一页中。但如上所述,情况似乎并非如此。在第二遍中,它是如何变成 6/3 的?
    • @FrankQ.:对不起;我使用文件而不是页面来学习这一点。但是这些页面被分组到更大的集合中,以保存更长的记录序列。您想为每个组保留一个缓冲区页面,并在合并到达该组时按顺序从该组中提取每个页面。对于第 2 阶段,组现在大小为 20 页(来自 4 个大小为 5 的组),因此只有 6 个组。
    猜你喜欢
    • 2012-05-07
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    相关资源
    最近更新 更多