对于通用排序,答案似乎是否定的,因为快速排序,合并排序和堆排序往往在平均和最差情况下表现更好。但是,插入排序似乎在增量排序方面表现优异,即在保持列表排序的同时,在一段时间内一次向列表添加元素,尤其是在插入排序实现为链接列表时(O(log) n)平均情况与O(n))。但是,堆似乎能够(或几乎)执行增量排序(从堆中添加或删除单个元素具有O(log n)的最坏情况)。那么插入排序究竟与其他基于比较的排序算法或堆有什么关系呢?
答案 0 :(得分:50)
来自http://www.sorting-algorithms.com/insertion-sort:
虽然它是基本排序算法之一 O(n 2 )最坏情况时间,插入排序 是什么时候选择的算法 数据几乎排序(因为它 是自适应的)或当问题的大小 很小(因为它很低 开销)。
由于这些原因,并且因为它也是稳定的,插入排序是 经常用作递归基础案例 (当问题规模很小时) 更高的开销分而治之 排序算法,例如合并排序 或快速排序。
答案 1 :(得分:15)
算法分析中的一个重要概念是渐近分析。在两个具有不同渐近运行时间的算法的情况下,例如一个O(n ^ 2)和一个O(nlogn),分别是插入排序和快速排序的情况,不确定一个比一个更快另一个。
这种分析的重要区别在于,对于足够大的N ,一种算法将比另一种算法更快。在将算法分析为像O(nlogn)这样的术语时,会删除常量。在实际分析算法的运行时,这些常数仅对小n的情况很重要。
那是什么意思?这意味着对于某些小n,某些算法更快。 EmbeddedGurus.net的这个article包含了在有限空间(16k)和有限内存系统的情况下选择不同排序算法的有趣视角。当然,文章仅引用了对20个整数的列表进行排序,因此n的较大顺序无关紧要。更短的代码和更少的内存消耗(以及避免递归)最终是更重要的决定。
插入排序的开销很低,可以相当简洁地编写,它有两个主要优点:它是稳定的,并且当输入接近排序时它具有相当快的运行情况。
答案 2 :(得分:8)
是的,有理由使用插入排序或其变体之一。
这里其他答案的排序方法(快速排序等)假设数据已经在内存中并准备就绪。
但是,如果您试图从较慢的外部源(比如硬盘驱动器)读取大量数据,则会浪费大量时间,因为瓶颈显然是数据通道或驱动器本身。它跟不上CPU。在任何阅读过程中都会发生一系列自然等待。这些等待是 浪费的CPU周期 ,除非您将它们用于 排序 。
例如,如果您要解决此问题,请执行以下操作:
如果您在两个主题中执行以下操作,则可能需要更长的时间。
主题A:
主题B:
...以上将允许您使用否则浪费的时间。注意:线程B不会妨碍线程A的进度。
当数据被完全读取时,它将被排序并准备好使用。
答案 3 :(得分:4)
对于非常小的数据集,大多数排序过程将使用快速排序然后插入排序。
答案 4 :(得分:1)
如果您正在讨论维护已排序的列表,那么对某种树没有任何优势,它只会更慢。
好吧,也许它消耗更少的内存或更简单的实现。
插入排序列表将涉及扫描,这意味着每个插入都是O(n),因此排序n个项目变为O(n ^ 2)
插入容器(如平衡树)通常是log(n),因此排序为O(n log(n)),这当然更好。
但对于小型名单,它几乎没有任何区别。如果你必须自己编写没有任何库,列表很小和/或你不关心性能,你可以使用插入排序。
答案 5 :(得分:1)
YES,
插入排序比短列表上的快速排序更好。
实际上,最佳快速排序具有停止的大小阈值,然后整个数组按插入排序超过阈值限制。
也...
为了维护记分牌,二进制插入排序可能会很好。
请参阅this page。
答案 6 :(得分:0)
对于小型数组,插入排序的执行速度比快速排序快。 Java 7和Java 8 使用双轴快速排序来对基本数据类型进行排序。 双枢轴快速排序执行典型的单枢轴快速排序。根据双枢轴快速排序算法:
定义插入排序为小数组执行快速排序,这就是切换到长度小于27 的数组的插入排序的原因。原因可能是插入排序没有递归。
来源:http://codeblab.com/wp-content/uploads/2009/09/DualPivotQuicksort.pdf