Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我们为什么要使用n路合并?与双向合并相比,它有哪些优势?_Algorithm_Sorting - Fatal编程技术网

Algorithm 我们为什么要使用n路合并?与双向合并相比,它有哪些优势?

Algorithm 我们为什么要使用n路合并?与双向合并相比,它有哪些优势?,algorithm,sorting,Algorithm,Sorting,我试着读了几篇关于n-waymerge的文章,但不理解这个概念。我不明白为什么要使用n路合并而不是2路合并?比如,为什么要将数组分成3部分,对它们进行排序,然后对2部分进行双向合并,然后对第3部分进行双向合并,合并后的2部分:) 谢谢在“正常”合并排序中,将数组除以2,直到达到深度log2n,然后开始合并。两个大小为m的数组的每次合并也需要2m操作 这将使您得到以下公式(在计时分析中): n/2*2+n/4*4+。。。1*n=n*log2n 现在,如果进行三向合并,则将数组除以3。与前一种方法的

我试着读了几篇关于n-waymerge的文章,但不理解这个概念。我不明白为什么要使用n路合并而不是2路合并?比如,为什么要将数组分成3部分,对它们进行排序,然后对2部分进行双向合并,然后对第3部分进行双向合并,合并后的2部分:)

谢谢

在“正常”合并排序中,将数组除以2,直到达到深度
log2n
,然后开始合并。两个大小为
m
的数组的每次合并也需要
2m
操作

这将使您得到以下公式(在计时分析中):

n/2*2+n/4*4+。。。1*n=n*log2n 现在,如果进行三向合并,则将数组除以3。与前一种方法的区别有两个:

  • 分割深度现在是
    log3n
  • 在合并过程中,不需要比较两个元素,而需要找到至少三个元素
这意味着,在最基本的实现中,您将得到这样一个公式:

n/3 * 2*3 + n/9 * 2*9 + ... 1 * 2*n = 2 * n * log3n n/3*2*3+n/9*2*9+。。。1*2*n=2*n*log3n 请注意,2是相乘的,因为查找三个元素中的最小值包含2个操作

渐近地,这两个都是
Θ(nlogn)
。然而,也许(我没有尝试过)在实践中,三向合并排序会提供更好的性能,因为它的
log3n
。然而,由于n=1000000的
log2n
仅为20,而相同数字的
log3n
为12.5,我怀疑这种优化是否真的有效,除非
n
相当大


通过巧妙的实现,k路合并可能确实对合并排序有很好的影响。其思想是,一旦找到了
k
元素的最小值,就已经知道了其余
k-1
元素之间的关系,这些元素不是最小值。因此,一旦从其各自的列表中使用了最小元素,您只需比较该列表的新值,并找到其相对于剩余
k-1
元素的顺序。使用堆,这将非常简单



一定要看到。我同意他的观点,多路合并的真正威力来自于处理多个磁盘和并行处理。

在进行外部排序时,通常会有多个要合并的流。例如,假设您需要对一TB的数据进行排序,并且只有(比如)64GB的RAM

您通常会通过读取64GB的数据,对其进行排序,然后将其写出。对整个TB的数据重复上述操作,为可以同时保存在内存中的每个“块”生成一个中间文件。有很多方法可以改进这一点,但您通常希望得到的最好结果是,您可以生成每个大约128GB的已排序中间文件

这就给您留下了许多要合并在一起的中间文件,而且这个数字几乎肯定会大于2


如果你经常这样做,你可能有一些相当高端的硬件来做。如果您将每个中间文件放在一个单独的磁盘驱动器上(并且至少还有一个用于输出),您几乎可以肯定地通过一次将所有数据合并在一起而不是一次仅合并两个数据来提高速度。该过程通常是I/O绑定的,因此一次读取(比如)8个磁盘的速度通常是一次仅读取2个磁盘的速度的4倍左右(尽管这取决于您的输出磁盘具有如此大的带宽,这可能不是真的)。通过避免创建更多的中间文件(需要进一步合并),您的总体速度可能会提高更大的因数。

我想说,并行计算和并行磁盘读取可能是主要原因。很好,谢谢Shahbaz,这真的是一个很好的解释现在我不明白的部分是,在分成3人一组后,你将如何进行合并?在我知道3分后,我会怎么做?假设我把它放在3元素数组的开头,那么接下来的2个元素呢?你能给我指出一个简单的示例代码吗?抱歉,这听起来可能很愚蠢,但这是我在3路合并中从未掌握的部分。与处理2个数组合并时所做的相同。每个数组都有一个指针指向尚未合并的部分(在开始时,它将是数组的开始)。找到最小值后,将其放入合并数组中,并前进与该元素对应的指针。这也是同样的问题,您有三个指针,查找最小值,将其附加到合并数组中,并前进该指针。重复一遍。 n/3 * 2*3 + n/9 * 2*9 + ... 1 * 2*n = 2 * n * log3n