快速排序和合并顺序数据在内存中适合的性能与访问磁盘上的顺序数据的速度慢
以下引文来自维基百科合并排序页面的“与其他排序算法的比较”部分
在典型的现代体系结构上,高效的快速排序实现通常优于合并排序,以便对基于 RAM 的阵列进行排序。[需要引用]另一方面,合并排序是一种稳定的排序,在处理访问速度慢的顺序媒体时效率更高。
我的问题:
为什么当要排序的数据都可以放入内存时,Quicksort 的性能优于 Mergesort?如果所需的所有数据都已缓存或在内存中,那么快速排序和合并排序的访问速度不是很快吗?
为什么 Mergesort 在处理访问速度慢的顺序数据(例如,在要排序的数据不能全部放入内存的情况下从磁盘)方面更有效率?
(从我下面的评论移到这里)在 n 个元素的基元数组(数据是连续的)中。必须在 MergeSort 中读取和比较的元素对是 和(在最终合并中发生)。现在认为必须在 QuickSort 中读取和比较的一对元素是 和 (发生在第一个分区中,假设我们将随机选择的透视与第一个元素交换)。我们知道数据是以块的形式读取并加载到缓存中,或者磁盘到内存(如果我错了,请纠正我),那么在使用MergeSort时,所需的数据是否更有可能加载到一个块中?在我看来,MergeSort总是占上风,因为它可能会比较更紧密的元素。我知道这是假的(见下图),因为QuickSort显然更快......我知道MergeSort没有到位,需要额外的内存,这可能会减慢速度。除此之外,我在分析中遗漏了哪些部分?
arr
arr[0]
arr[n/2]
arr[1]
arr[n]
图像来自普林斯顿CS MergeSort和QuickSort幻灯片
我的动机:
我想了解上述这些概念,因为它们是为什么mergeSort在对LinkedList进行排序时是首选的主要原因之一,或者在对数组或顺序数据进行排序时没有顺序数据和quickSort是首选的主要原因之一。为什么mergeSort用于对Java中的对象进行排序,而quickSort用于对Java中的基元类型进行排序。
更新:Java 7 API实际上使用TimSort对Object进行排序,Object是MergeSort和InjectSort的混合体。对于基元,双透视快速排序。这些更改是从 Java SE 7 开始实现的。这与排序算法的稳定性有关。为什么Java的Arrays.sort方法对不同类型的使用两种不同的排序算法?
编辑:
我将不胜感激解决以下方面的回答:
- 我知道这两种排序算法在移动次数、读取次数和比较次数上有所不同。如果这些是导致我在问题中列出的行为的原因(我怀疑它),那么对排序算法的步骤和过程如何导致它具有从磁盘或内存中寻求数据的优点或缺点的彻底解释将不胜感激。
- 欢迎举例说明。我通过例子学得更好。
注意:如果您正在阅读@rcgldr的答案。看看我们在聊天室的对话,它有很多很好的解释和细节。https://chat.stackoverflow.com/rooms/161554/discussion-between-rcgldr-and-oliver-koo