算法介紹
冒泡算法1956年開始就有人開始研究。
冒泡排序的基本思想就是:每次比較兩個相鄰元素,如果他們的順序錯誤就把它們交換過來。
舉個栗子
例如我們需要將 12,35,99,18,76 5個數進行從大到小排序,既然是從大到小排序,也就是越小越靠後。
首先比較第一個數和第二個數,第一個是12,第二個是35,發現12 小於35,由於是越小越靠後,因此要對這兩個數交換位置,那麼交換後的順序爲 35,12,99,18,76。按照之前的方法,我們比較第二個和第三個數,第二個是12第三個是99,99大於12,所以要交換兩個數的位置,交換過的順序爲 35,99,12,18,76。一次類推,可以通過下圖來看12的位置變化:
12,35,99,18,76 第一次交換
35,12,99,18,76 第二次交換
35,99,12,18,76 第三次交換
35,99,18,12,76 第四次交換
35,99,18,76,12 第五次交換
進行五次交換後,就成功把最小的數12給排到最後面了。
這樣我們就將最小的數給歸位了,但是,其他四個數還沒就位,所以我們就要接着比較,我們在上次排序的基礎上,拿第一個數35和第二個數99進行排序,發現99大於35,因此進行交換,交換之後爲99,35,18,76,12 ,就這樣按着第一趟的方法依次比較,最後得到的順序爲:99,35,76,18,12.這樣第二小的數18 成功歸位。
按照上面的方法,在進行三次排序,最後就能實現從大到小的排序了。
現在我們回憶一下,每次都比較相鄰的兩個數,,如果後面的數比前面的大,兩個數就進行交換位置,一直比較下去最小的一個數就在最後一位了,就如同一個氣泡,一步步向上翻滾,最後成功浮出水面,隨意這個排序方法就有個很好聽的名字,冒泡排序,相信大家最熟悉的排序也就是他了,誰叫他的名字這麼好記呢。
代碼實現
下面我們就用代碼實現一下:
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a[100],i,j,t,n;
scanf("%d",&n); //輸入n個數
for (i = 1; i <= n; i++) {
scanf("%d",&a[i]);
}
for (i = 1; i < n-1; i++) { //n個數排序,只進行n-1趟
for (j = 1; j < n-i; j++) { //從第一位開始,知道最後一位數
if (a[j] < a[j+1]) {
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
for (i = 1; i <= n; i++) {
printf("%d ",a[i]);
}
printf("\n");
return 0;
}
相信大家都能看懂上面的代碼。我就不在細講了,大家可以去自己的編譯環境運行一下,好好琢磨一下。
時間複雜度
冒泡排序的核心部分是雙重嵌套循環,不難看出冒泡排序的時間複雜度爲O(N2)(N的2次冪),這是一個非常高的時間複雜度。
算法的優缺點
冒泡排序早在1956年就有人開始研究,之後有很多人嘗試着改進該算法,但結果卻是令人失望的,如Doonald E.Knuth 1974年所說:冒泡排序除了他迷人的名字和導致了某些有趣的理論問題之外,似乎沒有什麼值得推薦的。