【问题标题】:Why is mergesort better for linked lists?为什么归并排序更适合链表?
【发布时间】:2011-11-29 14:28:38
【问题描述】:

为什么在对列表进行排序而不是快速排序时,归并排序被认为是“可行的方法”? 我在网上观看的一次讲座中听到了这一点,并在几个网站上看到了它。

【问题讨论】:

标签: sorting data-structures quicksort mergesort


【解决方案1】:

快速排序的主要效率来源之一是locality of reference,其中计算机硬件经过优化,因此访问彼此靠近的内存位置往往比访问分散在内存中的内存位置更快。快速排序中的分区步骤通常具有极好的局部性,因为它访问靠近前后的连续数组元素。因此,快速排序往往比堆排序等其他排序算法的性能要好得多,尽管它经常进行大致相同数量的比较和交换,因为在堆排序的情况下,访问更加分散。

此外,快速排序通常比其他排序算法快得多,因为它就地操作,无需创建任何辅助数组来保存临时值。与合并排序之类的东西相比,这可能是一个巨大的优势,因为分配和释放辅助数组所需的时间可能很明显。就地操作也提高了快速排序的局部性。

使用链表时,这些优点都不一定适用。因为链表单元通常分散在整个内存中,所以访问相邻链表单元没有局部性。因此,快速排序的巨大性能优势之一被吃掉了。同样,就地工作的好处不再适用,因为归并排序的链表算法不需要任何额外的辅助存储空间。

也就是说,快速排序在链表上仍然非常快。合并排序往往更快,因为它更均匀地将列表分成两半,并且每次迭代执行合并的工作比执行分区步骤少。

希望这会有所帮助!

【讨论】:

  • 在第 3 段的最后一行中,您写道“同样,原地工作的好处不再适用,因为合并排序的链表算法不需要任何额外的辅助存储空间。”。为什么不需要辅助存储空间?
  • @Geek 我可能应该说“合并排序的链表算法不需要 O(n) 辅助存储空间。”标准的基于数组的合并算法要求您在执行合并的过程中分配额外的存储空间,因为元素需要四处移动。在使用链表的合并排序中,可以通过简单地重新链接元素来移动元素而无需分配外部数组。
【解决方案2】:

find() 的开销比合并排序对快速排序的危害更大。

归并排序对数据执行更多“短程”操作,使其更适合链表,而快速排序更适用于随机访问数据结构。

【讨论】:

  • find() 是什么意思?
  • 在数据结构中寻找条目。对于链接的 linst,您总是在前进/倒带,就像播放磁带一样。
  • 在链表情况下,您不需要使用数组上使用的随机访问分区函数进行快速排序。您可以通过遍历列表并将每个元素分配到三个列表之一中来划分链表——“小于”列表、“大于”列表和“相等列表”,然后在后两个列表上递归。你说得对,标准分区很慢,但这并不会使链表快速排序变慢。
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 2012-08-23
  • 2015-07-19
  • 2011-07-10
  • 2014-08-02
  • 2020-03-25
相关资源
最近更新 更多