浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析以后续补充说明(有图有真相)

   若是你以为个人有些话有点唐突,你不理解能够想看看前一篇《C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析》html

  这几天闲着没事就写了一篇《C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析》的随笔,因为当时有点脑残把希尔排序写错了,致使其性能不少状况下都查过了快速排序。当时我就怀疑个人算法的正确性了,因为当时的激动没来得及检查,我直呼难以想象,以致于让快速排序任希尔排序作了老爷O(∩_∩)O哈哈~,这晚辈太不敬了。感谢博友“堕落的恶魔”给我指了出来,同时和各位博友交流的过程也让我长见识了。正确的快速排序我已经更改过来了,你们不要受我以前的误导。如今从新测试一遍。面试

 排序算法时间复杂度和空间复杂度对比:算法

  

               注意:基数排序中的d是最大数的次数,r是桶数。安全

  再和博友讨论以后,作了一些改进。dom

  一、改进Swap()算法为:性能

  

1 inline void Swap(int &a,int &b) 2 { 3 
4     a=a^b; 5     b=a^b; 6     a=a^b; 7 }

这里看上去彷佛很完美,多简洁明了啊!!但是当我打印出结果一看我和个人小伙伴都惊呆了!!!!!以下图:学习

待排序数为:int a[20]={25,19,6,58,34,10,7,98,160,0,345,445,675,34,7,122,8,435,23,678};测试

可结果以下图:优化

分析发现:若是Swap(a,a)就会把a置零,而若是a=3,b=3,Swap(a,b)则不影响。尼玛,这么多陷阱!而后改代码以下:ui

1 inline void Swap(int &a,int &b) 2 { 3     if(a!=b) 4  { 5         a=a^b; 6         b=a^b; 7         a=a^b; 8  } 9 }

如今对比改进前和改进后的效率对比用快速排序测试1千万个数据。

改进前:

改进后:

总结:实践发现效率并无升高,反而下降了。看来这种改进并无什么直接的做用,固然这里有一个影响的因素是两组测试的数据只是个数相等。具体值都是用程序生成的随机数。

   二、改进快速排序:

    主要改进了基准值的选取是随机的。

    改进代码:

 1 //快速排序
 2 ///////////////////////////////////////  3 inline void Swap(int &a,int &b)  4 {  5     int temp;  6     temp=a;  7     a=b;  8     b=temp;  9 // if(a!=b) 10 // { 11 // a=a^b; 12 // b=a^b; 13 // a=a^b; 14 // }
15 } 16 
17 int Partition(int a[],int p,int r) 18 { 19     int i=p; 20     int j=r+1; 21     int x=a[p]; 22     while (true) 23  { 24         while(a[++i]<x&&i<r); 25         while(a[--j]>x); 26         if (i>=j)break; 27  Swap(a[j],a[i]); 28 
29  } 30     a[p]=a[j]; 31     a[j]=x; 32     return j; 33 } 34 inline int Random(int p,int r) 35 { 36     return (p+(rand()%(r-p+1)));//p=<x<=r
37 } 38 
39 int RandomPartition(int a[],int p,int r ) 40 { 41     int i=Random(p,r); 42  Swap(a[i],a[p]); 43     return Partition(a,p,r); 44 } 45 
46 void QuickSort(int a[],int p,int r) 47 { 48     if (p<r) 49  { 50         int q=RandomPartition(a,p,r); 51         QuickSort(a,p,q-1); 52         QuickSort(a,q+1,r); 53  } 54 }

 

改进前:

改进后:

 

小结:尼玛,这神马状况。这效率越改越低,哪位大侠有更好的改进方法能够交流一下。

  三、接下来我重测一下排序英雄榜(昨天测的你们就当看笑话了O(∩_∩)O

      今天博友 Sam Xiao提供一种前所未见的排序算法(我称之为SomeoneSort算法),其效率之低让人叹为观止(感受时间复杂度接近O(n!))!固然这里并无嘲笑的意思,多一种方法,多一种思路学习一下都是不错的。拿出来和你们分享一下:

 1 //从未见过效率如此低的排序算法
 2 void SomeoneSort(int a[],int n)  3 {  4     //int count=0;
 5     int i=0;  6     while (i<n-1)  7  {  8         if(a[i]>a[i+1])  9  { 10             Swap(a[i],a[i+1]); 11             i=0; 12             //count++;
13             continue; 14  } 15         i++; 16  } 17     //cout<<count<<"次"<<endl;
18 }

 

下面拿SomeOneSort和BulbleSort对比一下:

下面从新测一下昨天7个排序算法,具体改过的只有快速排序和希尔排序:

数据量1:

数据量10:

数据量100:

数据量1000:

数据量10000:

数据量50000:

数据量100000:

数据量200000:

 

数据量300000:

 

数据量1百万:

 

数据量1千万:

 

数据量1亿:

 

数据量5亿:

 

数据量5亿:

 

数据量5.2亿:

  总结:昨天和今天两天啥事没干就是在测试这些算法,收获不少。首先算法的好坏不能一律而论,得看具体状况。具体状况就是指待排的数据量,和你能承受的内存空间。好比基数排序在数据量在1w~20w之间 高于快速排序,可是这是须要空间做为代价的。30w后基数排序就挂,固然这可能和个人编码有关。可是从整体性能来讲,应该是知足这一规律的,快速排序一路测下来确实表现的很好,可是在代码的健壮性方面可能不及希尔排序,就效率将希尔排序和快速排序是一个数量级上的固然我得认可这些排序代码我并无真正用于实际的项目中,每每只是对付笔试和面试。本人小本科一枚,最近忙着找工做,因此遇到了就在复习复习。真正用于项目中确定还有许多须要优化和改进的地方。或者是组合多种排序算法,使之成为一个更复杂效率更高的算法。读书读到如今你们应该知道,生活中、学习中、工做中、以致于咱们搞算法、计算机安全领域。最好的接解决方案无非是根据实际状况各类因素的权衡,把手中的的多套方案进行妥协和折中,找一个最佳的平衡点。

  很快本身也要走进社会了,就像刚刚进入大学前的一段时间,心中尽是憧憬和期待,即使别人说社会是怎样怎样的复杂和现实。有的时候甚至会在想工做的第一个月的工资要干什么?好期待第一月的工资,其实我已经计划好了,O(∩_∩)O哈哈~。回顾大学的这将近四年。让我改变最大的仍是个人思想,我以为这也是最宝贵的,有为人处世方面的,也有学习方法方面的,至少如今个人自学能力比之前提升了不知道多少!基本上遇到的技术问题在互联网和图书管总能找到或多或少都能找到答案,固然咱们要珍惜老师上课的时光,我以为那是学习知识最快的方式。这一个多月来我学习的积极性是如此的高,从未有过!个人舍友们也是,咱们总是开玩笑说“要是大一就有如今的思想我早就怎么怎么了……”,若是你还不用面临毕业,那么以半个过来人的身份告诉你“好好地学习,好好学习一门你感兴趣的技术,若是你不肯定你对什么感兴趣你能够找一个你不至于讨厌的先学一学,慢慢发现你是否喜欢这个”根据个人经验你有足够时间尝试这样三次左右,固然这后最好找一个你感兴趣的领域好好的学习。切记不可三天打鱼两晒网,由于若是你手中掌握一门技能对你之后找工做是有很大好处的。做为一名很菜的“程序猿”,我必须明白与时俱进的学习新知识才能不断提升个人生产力。也才有能力养活本身,养活本身的家庭以及之后年迈的父母。你们一块儿加油!!!(很明显跑题了!!O(∩_∩)O哈哈~)

有不妥的地方欢迎你们指正!!共同窗习!!

最后声明一点:快速排序仍是希尔排序他爹!!

推荐一段博友分享的排序视频很艺术、很形象、很生动哦(http://www.oschina.net/question/561584_65522

相关文章
相关标签/搜索