📌  相关文章
📜  为什么“快速排序”首选用于数组,而“合并排序”首选用于链表?

📅  最后修改于: 2021-04-23 22:42:02             🧑  作者: Mango

为什么快速排序是数组的首选?

下面是数组的“快速排序”和“合并排序”的递归和迭代实现。

数组的递归快速排序。
数组的迭代快速排序。
递归合并数组排序
数组的迭代合并排序

  • 快速排序的一般形式是就地排序(即,不需要任何额外的存储),而合并排序则需要O(N)的额外存储,N表示数组大小,这可能会非常昂贵。分配和取消分配用于合并排序的额外空间会增加算法的运行时间。
  • 比较平均复杂度,我们发现两种类型的排序均具有O(NlogN)平均复杂度,但常量不同。对于数组,由于使用了额外的O(N)存储空间,合并排序会丢失。
  • 快速排序的大多数实际实现使用随机版本。随机版本的预期时间复杂度为O(nLogn)。在随机版本中也可能出现最坏的情况,但是对于特定模式(如排序数组)不会发生最坏情况,并且随机快速排序在实践中效果很好。
  • 快速排序也是一种缓存友好的排序算法,因为它在用于数组时具有良好的引用局部性。
  • 快速排序也是尾部递归的,因此完成了尾部调用优化。

为什么合并排序是链接列表的首选?

下面是Quicksort和Mergesort用于单链和双链列表的实现。

快速排序双重链接列表
快速排序单链接列表
合并单链接列表的排序
合并双链表的排序

  • 对于链表,情况有所不同,主要是由于数组和链表的内存分配不同。与数组不同,链接列表节点在内存中可能不相邻。
  • 与数组不同,在链表中,如果给定上一个节点的引用/指针,则可以在O(1)额外空间和O(1)时间的中间插入项目。因此,可以实现合并排序的合并操作而无需为链接列表提供额外的空间。
  • 在数组中,由于元素在内存中是连续的,因此我们可以进行随机访问。假设我们有一个整数(4字节)数组A,并且将A [0]的地址设为x,然后访问A [i],我们可以直接访问(x + i * 4)处的内存。与数组不同,我们不能在链表中进行随机访问。
  • 快速排序需要很多此类访问权限。在访问第i个索引的链表中,我们没有从头到第i个节点的每个节点,因为我们没有连续的内存块。因此,用于快速分类的开销增加了。合并排序按顺序访问数据,并且对随机访问的需求低。

相关文章:

  • 为什么quicksort比mergesort好?
  • 了解您的排序算法|设置1(编程语言使用的排序武器)
  • 迭代合并排序
  • 迭代快速排序