是否有充分的理由使用插入排序?

时间:2009-04-10 07:03:26

标签: algorithm computer-science

对于通用排序,答案似乎是否定的,因为快速排序,合并排序和堆排序往往在平均和最差情况下表现更好。但是,插入排序似乎在增量排序方面表现优异,即在保持列表排序的同时,在一段时间内一次向列表添加元素,尤其是在插入排序实现为链接列表时(O(log) n)平均情况与O(n))。但是,堆似乎能够(或几乎)执行增量排序(从堆中添加或删除单个元素具有O(log n)的最坏情况)。那么插入排序究竟与其他基于比较的排序算法或堆有什么关系呢?

7 个答案:

答案 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周期 ,除非您将它们用于 排序

例如,如果您要解决此问题,请执行以下操作:

  1. 在专用循环中读取大量数据到内存中
  2. 对该数据进行排序
  3. 如果您在两个主题中执行以下操作,则可能需要更长的时间。

    主题A:

    1. 阅读资料
    2. 将数据放入FIFO队列
    3. (重复直到数据从驱动器耗尽)
    4. 主题B:

      1. 从FIFO队列中获取数据
      2. 将其插入已排序列表中的适当位置
      3. (重复直到队列为空并且线程A表示“已完成”)。
      4. ...以上将允许您使用否则浪费的时间。注意:线程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 使用双轴快速排序来对基本数据类型进行排序。 双枢轴快速排序执行典型的单枢轴快速排序。根据双枢轴快速排序算法:

  1. 对于小型数组(长度<27),请使用“插入排序算法”。
  2. 选择两个支点...........
  3. 定义插入排序为小数组执行快速排序,这就是切换到长度小于27 的数组的插入排序的原因。原因可能是插入排序没有递归。

    来源:http://codeblab.com/wp-content/uploads/2009/09/DualPivotQuicksort.pdf