原始地址:C / C++演算法學習筆記(3)-冒泡法
冒泡法:
這是最原始,也是眾所周知的最慢的演算法了。它的名字的由來因為它的工作看來象是冒泡:
#include <iostream.h>void BubbleSort(int* pData,int Count){ int iTemp; for(int i=1;i<Count;i++) { for(int j=Count-1;j>=i;j--) { if(pData[j]<pData[j-1]) { iTemp = pData[j-1]; pData[j-1] = pData[j]; pData[j] = iTemp; } } }} void main(){ int data[] = {10,9,8,7,6,5,4}; BubbleSort(data,7); for (int i=0;i<7;i++) cout<<data[i]<<" "; cout<<"/n";}
圖示:
-----------------------------------------------------------------------------
比較前|第一次|第二次|第三次|第四次|第五次|第六次
10 10 10 10 10 10 4
9 9 9 9 9 4 10
8 8 8 8 4 9
9
7 7 7 4 8 8
8
6 6 4 7 7 7 7
5 4 6 6 6 6
6
4 5 5 5 5 5
5
-----------------------------------------------------------------------------
通過可以看出,冒泡法形象的描述來,4這個元素就像一個氣泡逐漸冒到上面來了。
我們排序的有7個元素,最壞的情況全部倒序,4這個元素要冒上來需要6次。因此,n個元素,最壞的情況,需要移動:1+2+3+ ...+(n-1)=1/2*n(n-1)次。
倒序(最糟情況)
第一輪:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,10,8,9->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
迴圈次數:6次
交換次數:6次
其他:
第一輪:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交換2次)
第二輪:7,8,10,9->7,8,10,9->7,8,10,9(交換0次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
迴圈次數:6次
交換次數:3次
上面我們給出了程式段,現在我們分析它:這裡,影響我們演算法效能的主要部分是迴圈和交換,顯然,次數越多,效能就越差。從上面的程式我們可以看出迴圈的次數是固定的,為1+2+...+n-1。寫成公式就是1/2*(n-1)*n。
現在注意,我們給出O方法的定義:
若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n) = O(g(n))。(呵呵,不要說沒學好數學呀,對於編程數學是非常重要的!!!)
現在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。所以我們程式迴圈的複雜度為O(n*n)。
再看交換。從程式後面所跟的表可以看到,兩種情況的迴圈相同,交換不同。其實交換本身同資料來源的有序程度有極大的關係,當資料處於倒序的情況時,交換次數同迴圈一樣(每次迴圈判斷都會交換),複雜度為O(n*n)。當資料為正序,將不會有交換。複雜度為O(0)。亂序時處於中間狀態。正是由於這樣的原因,我們通常都是通過迴圈次數來對比演算法。