各大排序算法优缺点对比

来源:互联网 发布:审美差异知乎 编辑:程序博客网 时间:2024/04/30 05:47

  我这里只总结各大算法知识的要点,如果你想看看算法思想和实现代码,网上的其他博客都很喜欢贴大段代码和文本,可以自己去看。

 

  (如果出错,请指正!感激不尽!)

 

一.三大简单、慢速排序算法

 

 

平均

最好

最坏

辅助存储

稳定性

直接插入

n^2

n

n^2

1

稳定

直接选择

n^2

n^2

n^2

1

不稳定

直接交换(冒泡)

n^2

n

n^2

1

稳定

 

我省略了O,如:上面的n^2其实是O(n^2)的意思

这三种算法的共同优点都是简单,共同缺点都是慢。

 

 

优点

缺点

直接插入

 

比较次数越少,移动次数越多

直接选择

 

 

直接交换(冒泡)

 

每次只移动相邻两个元素

 

 

二.希尔排序

                 n^1.3         n           n^2          1                不稳定

   希尔排序中,算法的效率很大程度由增量决定,而一个合适的增量的选择需要大量的经验。

 

 

三.堆排序

              nlog2n        nlog2n        nlog2n               1          不稳定

        nlog2n的2是下标,在这里不知道怎么设置,大家应该了解。

    它比快速排序的优点:在最坏情况下它的性能很优越

    它比归并排序的有点:使用的辅助存储少

    它的缺点: 不适合太小的待排序列(因为他需要建堆);不稳定,不适合对象的排序

 

四.快速排序、归并排序(最常用的排序算法)

 

平均

最好

最坏

辅助存储

稳定性

快速排序

nlog2n

nlog2n

n^2

1

不稳定

归并排序

nlog2n

nlog2n

nlog2n

n

稳定

       (分治法思想)

 

PS:二者各自的特点。

         快速排序最快的排序算法,缺点是不稳定,不适合对象排序;

         归并排序第二块的算法,缺点是辅存很大,适合对象排序;

PS:快速排序递归堆栈空间的占用:

        最优的情况下空间复杂度为:O(logn)  ;每一次都平分数组的情况

    最差的情况下空间复杂度为:O(n );退化为冒泡排序的情况

PS:一个排整数的测试:

         在笔记本上跑的,对1024*1024个随机整数排序,快速排序比合并排序快3到4倍。

         [05.0813:40:22] INFO: Performance Check: Quick Sort 1048576 Elements., took 94 ms

         [05.0813:40:22] INFO: Performance Check: Merge Sort 1048576 Elements., took 437 ms

 

五.以Java 集合类的sort()排序为例子(jdk不同版本sort()实现也不同)

   1.JDK6中的排序是基于传统的归并排序做了部分优化,这两个优化都很简单,实际上效率并未提高多少。所以在JDK7中将其替换为TimSort。

 

   2.JDK 7中,内部实现换成了TimSort,其对对象间比较的实现要求更加严格,

         (1)传入的待排序数组若小于阈值MIN_MERGE(Java实现中为32,Python实现中为64),则调用binarySort,这是一个不包含合并操作的 mini-TimSort。二分查找/折半插入查找,

从数组开始处找到一组连接升序或严格降序(找到后翻转)的数。

         (2)否则, 不断二分,直到小于阈值,然后插入排序;

         TimSort算法是一种起源于归并排序和插入排序的混合排序算法

 

   3.在jdk8中,如果你看过源码就会知道,其实针对不同的情况使用了不同的排序算法,简单罗列下:

         (1).如果是简单对象数据,例如int,double,且数组长度在一定阀值内,则使用快排,如果在阀值外,则用归并的变种;

         (2).如果是复杂对象数组,则如果数组长度在一定阀值以内,则使用折半插入排序,如果长度在阀值外,则使用归并法,但是如果归并二分后小于阀值了,则在内部还是会使用折半插入排序。。。以上只是大概

    大家一定注意到了,阈值以外需要使用归并,因为快排使用递归,如果待排序列太大的话,堆栈可能会溢出;而归并排序不存在此问题;

 

    我查阅了jdk8的新功能,其中好像并没有关于sort()的更新,这样说来,jdk7和8应该在sort()上没有区别才对;但是我在知乎上找到了关于jdk8 的sort()描述,好像还有很多人同意的样子,所以我就把他的言论给贴了过来。

   后来这一块还是没弄明白,发了个求助的帖子,有了结果后,我会修改这个博文的。若是有高手看到此处,还望不吝赐教啊!

 

 

 

原创粉丝点击