1. 程式人生 > >啊哈演算法 之 氣泡排序

啊哈演算法 之 氣泡排序

演算法介紹

冒泡演算法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年所說:氣泡排序除了他迷人的名字和導致了某些有趣的理論問題之外,似乎沒有什麼值得推薦的。