淺談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

相關文章
相關標籤/搜索