快速排序如何比归并排序更擅长于缓存局部性?

7

在涉及到快速排序归并排序的答案中, 通常会说快速排序归并排序更好地利用了缓存局部性(引用局部性)。

由于两种排序都采用了分治方法,我不明白为什么快速排序更加友好。有人能提供更多相关见解吗?

此外,还有关于原地归并排序的注释。如果这是可行的(我不知道是否可行),那么归并排序也可以成为缓存友好型吗?


这是一个好问题。至少在维基百科页面上我找不到答案。 - displayName
1个回答

8

如果您正在对适合缓存的数组进行排序,则快速排序将需要较少的内存访问,因为归并排序需要分配第二个数组。快速排序将数组加载到缓存中,然后继续而无需等待内存。归并排序将支付访问第二个数组的额外费用。

如果您要对不适合缓存的数组进行排序,则从局部性角度来看,快速排序仍然胜出,因为当它们递归地对较小的部分进行排序时,两种算法很快就会到达适合缓存的部分,对于这些部分,快速排序比上述论点更快。在不适合缓存的排序的较高级别上,从缓存局部性的角度来看,快速排序和归并排序表现几乎相同。


1
即使原地排序更复杂,归并排序也可以在没有额外数组的情况下实现,你的回答是否考虑了原地排序的版本? - dev_nut
实际上,并没有像常规归并排序一样具有O(N log N)复杂度的实用原地归并排序。 - Matt Timmermans
您能否在回答中详细阐述一下?这样,我认为所有的疑问都会得到澄清。 - dev_nut
2
不确定你的意思... 没有一个。你发布的链接表明他们的原地归并排序需要O(N^2)时间。有更好的、简单的变体,需要O(N log^2 N)的时间,但仍然比常规归并排序慢。有一些复杂的类似于归并排序的算法,可以在最小的额外空间下获得O(N log N)的时间,但它们足够复杂,以至于在现实生活中不会使用。 - Matt Timmermans
为了执行原地合并,您需要找到插入点来将右侧的子数组插入其中。这本身就是O(lg N)操作。再加上内存移动需要另外O(N)时间。因此,合并变为O(N lg N),这基本上缩减为只是另一种排序。还有次线性合并,但它实际上并没有“合并”子数组。 - garbagecollector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接