首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在合并排序中应该在阈值交叉之后使用插入排序

为什么在合并排序中应该在阈值交叉之后使用插入排序
EN

Stack Overflow用户
提问于 2012-09-27 21:01:09
回答 6查看 13K关注 0票数 6

我读过很多地方,对于像Merge-SortQuicksort这样的分而治之的排序算法,与其递归直到只剩下一个元素,不如在达到某个阈值时转移到Insertion-Sort,比如30个元素。这很好,但是为什么只有Insertion-Sort呢?为什么不是Bubble-SortSelection-Sort,它们都有类似的O(N^2)性能呢?Insertion-Sort只有在许多元素是预先排序的情况下才会派上用场(尽管Bubble-Sort也应该具有这种优势),但除此之外,为什么它应该比其他两个更高效呢?

其次,在this link,在第二个答案和随附的评论中,它说O(N log N)的表现比O(N^2)差,直到某个N。为什么呢?N^2的性能应该总是比N log N差,因为N > log N适用于所有N个>= 2,对吧?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-09-27 21:46:27

在实践中,

  1. 插入排序至少比冒泡排序快。它们的渐近运行时间是相同的,但插入排序具有更好的常量(每次迭代操作更少/更便宜)。最值得注意的是,它只需要线性数量的元素对交换,并且在每个内循环中,它执行n/2个元素中的每个元素与可以存储在寄存器中的“固定”元素之间的比较(而冒泡排序必须从内存中读取值)。例如,插入排序在其内部循环中比冒泡排序做的工作更少。
  2. 答案声称,对于“合理”n,10000 n lg n> 10 n²。这在大约14000个元素中是正确的。
票数 7
EN

Stack Overflow用户

发布于 2012-09-27 22:28:07

如果在达到阈值时退出分而治之的快速排序的每个分支,您的数据如下所示:

代码语言:javascript
运行
复制
[the least 30-ish elements, not in order] [the next 30-ish ] ... [last 30-ish]

插入排序有一个令人愉悦的特性,你可以在整个数组上只调用它一次,而且它的执行基本上与你对每30个块调用一次的效果相同。因此,您可以选择最后调用它,而不是在循环中调用它。这可能不会更快,特别是因为它需要额外的时间从缓存中提取整个数据,但根据代码的结构,这可能会很方便。

冒泡排序和选择排序都没有这个属性,所以我认为答案可能很简单:“方便”。如果有人怀疑选择排序可能更好,那么举证的责任就落在他们身上,以“证明”它更快。

注意,这种插入排序的使用也有一个缺点--如果您这样做,并且分区代码中有一个bug,那么只要它没有丢失任何元素,只是错误地对它们进行分区,您就永远不会注意到。

编辑:显然,这个修改是由Sedgewick完成的,他于1975年在QuickSort上写了他的PhD。最近,Musser (Introsort的发明者)对其进行了分析。参考https://en.wikipedia.org/wiki/Introsort

Musser还考虑了Sedgewick的延迟小排序对缓存的影响,在Sedgewick的延迟小排序中,小范围在插入排序的一次传递中在末尾排序。他报告说,它可以将缓存未命中的数量增加一倍,但它在双端队列中的性能要好得多,应该为模板库保留下来,部分原因是在其他情况下,立即进行排序的收益并不大。

在任何情况下,我不认为一般的建议是“无论你做什么,不要使用选择排序”。建议是,“插入排序比快速排序的输入大小小得惊人”,在实现快速排序时,这一点很容易证明给你自己。如果你想出了另一种在相同小数组上明显优于插入排序的排序,这些学术来源都没有告诉你不要使用它。我想令人惊讶的是,建议是一致的插入排序,而不是每个来源选择自己的最喜欢(坦率地说,入门教师对冒泡排序有着惊人的喜爱--我不会介意我再也不会听到它了)。插入排序通常被认为是小数据的“正确答案”。问题不在于它是否“应该”快,而在于它是否真的是快,而且我从来没有特别注意到有任何基准来驱散这个想法。

寻找这些数据的一个地方是Timsort的开发和采用。我很确定Tim Peters选择插入是有原因的:他不是在提供一般的建议,他是在优化一个真正有用的库。

票数 11
EN

Stack Overflow用户

发布于 2014-04-09 21:47:18

我很惊讶没有人提到一个简单的事实,即插入排序对于“几乎”排序的数据来说要快得多。这就是它被使用的原因。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12622015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档