为什么插入排序比快速排序更适合小的元素列表?

时间:2011-11-12 00:35:38

标签: algorithm quicksort insertion-sort

不插入排序O(n ^ 2)>快速排序O(nlogn)...所以对于小n,关系是否相同?

6 个答案:

答案 0 :(得分:20)

Big-O Notation描述了n很大时的限制行为,也称为渐近行为。这是近似值。 (见http://en.wikipedia.org/wiki/Big_O_notation

对于小n,插入排序更快,因为快速排序会带来额外的递归函数调用开销。插入排序也比快速排序更稳定,并且需要更少的内存。

此问题描述了插入排序的一些进一步的好处。 (Is there ever a good reason to use Insertion Sort?

答案 1 :(得分:10)

定义“小”。

在对排序算法进行基准测试时,我发现从快速排序切换到插入排序 - 尽管每个人都在说 - 实际上会损害大于4个元素的数组的性能(C中的递归快速排序)。这些数组可以使用与大小相关的最佳排序算法进行排序。

话虽如此,但请记住O(n...)只是比较次数(在这种特定情况下),而不是算法的速度。速度取决于实施,例如。例如,如果您的快速排序功能是否递归,以及处理函数调用的速度有多快。

最后但并非最不重要的是,大哦符号只是一个上限。

如果算法A需要10000 n log n比较且算法B需要10 n ^ 2,则第一个是O(n log n),第二个是O(n ^ 2)。然而,第二个(可能)会更快。

答案 2 :(得分:4)

O() - 符号通常用于表征大问题的性能,同时故意忽略常数因子和性能的附加偏移。

这很重要,因为处理器之间和实现之间的常数因素和开销会有很大差异:6502计算机上单线程Basic程序的性能与运行的C程序实现的算法非常不同英特尔i7级处理器。请注意,实施优化也是一个因素:即使所有其他因素都相同,对细节的关注通常也会使您获得重大的性能提升!

然而,常数因素和开销仍然很重要。如果您的应用程序确保N永远不会变得非常大,则O(N ^ 2)与O(N log N)的渐近行为不起作用。

插入排序很简单,对于小型列表,它通常比同等实现的快速排序或合并排序更快。这就是为什么实际的排序实现通常会依赖于“基本情况”的插入排序,而不是一直递归到单个元素。

答案 3 :(得分:3)

它是关于运行时间的常量问题,我们忽略了大符号(因为我们关注增长的顺序)。对于插入排序,运行时间是O(n ^ 2),即T(n)&lt; = c(n ^ 2),而对于Quicksort,它是T(n)<= k(nlgn)。由于c非常小,对于小n,插入排序的运行时间少于Quicksort的运行时间.....

希望它有所帮助...

答案 4 :(得分:0)

二进制插入排序怎么样?您绝对可以使用二分搜索来搜索要交换的位置。

答案 5 :(得分:0)

插入排序可以与快速排序结合使用的一个很好的现实示例是qsortglibc函数的实现。

首先要指出的是qsort通过堆栈实现quicksort算法,因为它消耗的内存更少,而堆栈是通过宏指令实现的。

source code中当前实现的摘要(如果您查看一下,将会通过注释找到很多有用的信息):

  
      
  1. 非递归

  2.   
  3. 使用三位数中值决策树选择枢轴元素

  4.   
  5. 仅快速排序TOTAL_ELEMS个/ MAX_THRESH个分区     插入排序以对每个分区中的MAX_THRESH个项目进行排序。     这是一个巨大的胜利,因为插入式排序对于小型(大多数情况下)更快     排序的数组段。

  6.   
  7. 两个子分区中较大的一个始终被推到     首先堆叠

  8.   

MAX_THRESH值代表什么?好吧,只是一个小的常数魔术值,

  选择

在Sun 4/260上运行最佳。