K-way合并的最大K
Maximum K for K-way merge
我想知道,K 向归并排序的最大 K 是多少,或者是否有最大值。
该算法的时间复杂度为 O(nlogK)。我一直在寻找它几个小时,但没有运气。有人可以 link 我到一些解释它的文章,或者告诉我是否有一些限制,为什么会这样?
另外我想知道是否有推荐使用的 K 值,这是最有效的。
在内部(仅内存)排序的情况下,无论 K 为何,对数据的操作总数大致相同。令 x = n log2(n)。 2 路归并排序需要 x 次移动,最坏情况下 x 比较总共 x + x = (2)x 次操作。 (从技术上讲,即使在最坏的情况下,也比 x 比较少一点,但 x 足够接近,可以理解这里的想法)。 4 路合并排序需要 (1/2)x 次移动和最坏情况 (3/2)x 比较,因此总共 (1/2)x + (3/2)x = (2)x 操作。如果比较快于移动,则 4 路归并排序更快,如果移动快于比较,则 2 路归并排序更快。还有指针或索引等变量保存在寄存器或堆栈中的问题,对于 4 路合并,您需要 16 个寄存器(如 64 位模式下的 X86)。作为移动速度更快的示例,请考虑对对象指针数组进行排序的情况,仅移动指针,但比较对象(这涉及对每个对象的指针取消引用)。
对于外部排序,在外部设备(磁盘驱动器,或者过去是一堆磁带驱动器)上创建排序块的内部排序可以是任何算法,K 路部分只是合并块.在外部排序传递的数量和足够大的 K 之间存在权衡,以便 K 路合并成为 cpu 绑定而不是 I/O 绑定。总时间为I/O次+超过I/O次的任何cpu次。 Gnu 对大数据文件的排序使用 K = 16。K 方式合并是使用 K 元素最小堆完成的,其中每个堆条目对应一个结构(或等效结构),该结构包含块 ID、记录索引或指针、数字内存中剩余的块的记录数,块中剩余的记录数)。初始创建K个表项的最小堆后,堆的前端元素对应K个表项中当前最小元素(假设升序)的结构。该元素被移动以输出,下一个元素从该块中读取,并且堆被更新以反映下一个元素放置堆中前端条目的位置。一旦到达块的末尾,合并就变成 K-1 合并,然后是 K-2 合并,直到只剩下 1 个块被复制。
我想知道,K 向归并排序的最大 K 是多少,或者是否有最大值。 该算法的时间复杂度为 O(nlogK)。我一直在寻找它几个小时,但没有运气。有人可以 link 我到一些解释它的文章,或者告诉我是否有一些限制,为什么会这样? 另外我想知道是否有推荐使用的 K 值,这是最有效的。
在内部(仅内存)排序的情况下,无论 K 为何,对数据的操作总数大致相同。令 x = n log2(n)。 2 路归并排序需要 x 次移动,最坏情况下 x 比较总共 x + x = (2)x 次操作。 (从技术上讲,即使在最坏的情况下,也比 x 比较少一点,但 x 足够接近,可以理解这里的想法)。 4 路合并排序需要 (1/2)x 次移动和最坏情况 (3/2)x 比较,因此总共 (1/2)x + (3/2)x = (2)x 操作。如果比较快于移动,则 4 路归并排序更快,如果移动快于比较,则 2 路归并排序更快。还有指针或索引等变量保存在寄存器或堆栈中的问题,对于 4 路合并,您需要 16 个寄存器(如 64 位模式下的 X86)。作为移动速度更快的示例,请考虑对对象指针数组进行排序的情况,仅移动指针,但比较对象(这涉及对每个对象的指针取消引用)。
对于外部排序,在外部设备(磁盘驱动器,或者过去是一堆磁带驱动器)上创建排序块的内部排序可以是任何算法,K 路部分只是合并块.在外部排序传递的数量和足够大的 K 之间存在权衡,以便 K 路合并成为 cpu 绑定而不是 I/O 绑定。总时间为I/O次+超过I/O次的任何cpu次。 Gnu 对大数据文件的排序使用 K = 16。K 方式合并是使用 K 元素最小堆完成的,其中每个堆条目对应一个结构(或等效结构),该结构包含块 ID、记录索引或指针、数字内存中剩余的块的记录数,块中剩余的记录数)。初始创建K个表项的最小堆后,堆的前端元素对应K个表项中当前最小元素(假设升序)的结构。该元素被移动以输出,下一个元素从该块中读取,并且堆被更新以反映下一个元素放置堆中前端条目的位置。一旦到达块的末尾,合并就变成 K-1 合并,然后是 K-2 合并,直到只剩下 1 个块被复制。