简体   繁体   English

合并 k 个排序数组 - 优先队列与传统合并排序合并,何时使用哪个?

[英]Merging k sorted arrays - Priority Queue vs Traditional Merge-sort merge, when to use which?

Assuming we are given k sorted arrays (each of size n ), in which case is using a priority heap better than a traditional merge (similar to the one used in merge-sort) and vice-versa?假设我们有k排序数组(每个大小为n ),在这种情况下使用优先级堆比传统合并(类似于合并排序中使用的那个)更好,反之亦然?

Priority Queue Approach: In this approach, we have a min heap of size k (initially, the first element from each of the arrays is added to the heap).优先队列方法:在这种方法中,我们有一个大小为k最小堆(最初,每个数组的第一个元素被添加到堆中)。 We now remove the min element (from one of the input arrays), put this in the final array and insert a new element from that same input array.我们现在删除 min 元素(从输入数组之一),将其放入最终数组并从同一输入数组中插入一个新元素。 This approach takes O(kn log k) time and O(kn) space.这种方法需要O(kn log k)时间和O(kn)空间。 Note: It takes O(kn) space because that's the size of the final array and this dominates the size of the heap while calculating the asymptotic space complexity.注意:它需要O(kn)空间,因为这是最终数组的大小,这在计算渐近空间复杂度时支配了堆的大小。

Traditional Merge: In this approach, we merge the first 2 arrays to get a sorted array of size 2n .传统合并:在这种方法中,我们合并前 2 个数组以获得大小2n的排序数组。 We repeat this for all the input arrays and after the first pass, we obtain k/2 sorted arrays each of size 2n .我们对所有输入数组重复此操作,在第一遍之后,我们获得k/2排序数组,每个数组的大小2n We repeat this process until we get the final array.我们重复这个过程,直到我们得到最终的数组。 Each pass has a time complexity of O(kn) since one element will be added to the corresponding output array after each comparison.每次通过的时间复杂度为O(kn)因为每次比较后都会将一个元素添加到相应的输出数组中。 And we have log k passes.我们有 log k 次传球。 So, the total time complexity is O(kn log k) .因此,总时间复杂度为O(kn log k) And since we can delete the input arrays after each pass, the space used at any point is O(kn) .由于我们可以在每次通过后删除输入数组,因此任何一点使用的空间都是O(kn)

As we can see, the asymptotic time and space complexities are exactly the same in both the approaches.正如我们所见,这两种方法的渐近时间和空间复杂度完全相同。 So, when exactly do we prefer one over the other?那么,究竟什么时候我们更喜欢一个呢? I understand that for an external sort the Priority Queue approach is better because you only need O(k) in-memory space and you can read and write each element from and back to disk.我知道对于外部排序,优先队列方法更好,因为您只需要O(k)内存空间,并且您可以从磁盘读取和写入每个元素。 But how do these approaches stack up against each other when we have enough memory?但是当我们有足够的内存时,这些方法如何相互叠加?

The total number of operations, compares + moves, is about the same either way.操作总数,比较 + 移动,无论哪种方式都大致相同。 A k-way merge does more compares but fewer moves. k-way 合并进行更多的比较但移动更少。 My system has an 8 way cache (Intel 3770K 3.5 ghz), which in the case of a 4 way merge sort, allows for 4 lines of cache for the 4 input runs and 1 line of cache for the merged output run.我的系统有一个 8 路缓存(Intel 3770K 3.5 ghz),在 4 路合并排序的情况下,允许 4 行缓存用于 4 次输入运行,1 行缓存用于合并输出运行。 In 64 bit mode, there are 16 registers that can be used for working variables, 8 of them used for pointers to the current and end position of each "run" (compiler optimization).在 64 位模式下,有 16 个寄存器可用于工作变量,其中 8 个用于指向每次“运行”(编译器优化)的当前和结束位置的指针。

On my system, I compared a 4 way merge (no heap, ~3 compares per element moved) versus a 2 way merge (~1 compare per move, but twice as many passes), the 4 way has 1.5 times the number of compares, but 0.5 times the number of moves, so essentially the same number of operations, but the 4 way is about 15% faster due to cache issues.在我的系统上,我比较了 4 路合并(无堆,每个元素移动 ~3 次比较)与 2 路合并(每次移动 ~1 次比较,但传递次数是两倍),4 路合并的次数是 1.5 倍,但是移动次数的 0.5 倍,所以基本上相同的操作次数,但是由于缓存问题,4 路大约快 15%。

I don't know if 16 registers is enough for a 6 way merge to be a tiny bit faster, and 16 register is not enough for an 8 way merge (some of the working variable would be memory / cache based).我不知道 16 个寄存器是否足以让 6 路合并速度稍微快一点,而 16 个寄存器不足以进行 8 路合并(一些工作变量将基于内存/缓存)。 Trying to use a heap probably wouldn't help as the heap would be memory / cache based (not register based).尝试使用堆可能无济于事,因为堆将基于内存/缓存(而不是基于寄存器)。

A k-way merge is mostly useful for external sorts, where compare time is ignored due to the much larger overhead of moves. k-way 合并最适用于外部排序,由于移动的开销更大,比较时间被忽略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM