1. 程式人生 > 實用技巧 >氣泡排序與改進

氣泡排序與改進

這個是參考大部分博主的,我想自己記下來

1.氣泡排序

顧名思義就是像吐泡泡一樣,把最大/最小的放著最左端或者最右端。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void bsort(vector<int> &n);
int main() {
    vector<int> n{4,5,2,3,6,8,9};
    bsort(n);
    return 0;
}
void bsort(vector<int
>& n) { int len = n.size(); int count = 0; //記錄比較次數 for (int i = 0; i < len; i++) { for (int j = 0; j < len-1-i; j++) { count++; if (n[j] > n[j + 1]) { int tmp = n[j]; n[j] = n[j + 1]; n[j + 1
] = tmp; } }     for (auto x : n) cout << x << " " ; cout << endl ; } cout << count << endl; }

我們可以看到,一共比較了21次。而且出現了一個問題從第二次迴圈開始到結束,排序的順便其實是都沒有變化的。也就是說我們做了很多無用功。

那麼我們就可以提出改進來優化氣泡排序。

2.初步優化

如果我們能判斷出該序列已經排好序了,就馬上停止排序,這樣就可以剩下一些步驟了。該怎麼辦呢?做標記

void bsort(vector<int>& n) {
    int len = n.size();
    int count = 0;
    for (int i = 0; i < len; i++) {
        bool flag = true;              //標記,如果判斷出來該序列已有序就馬上退出迴圈
        for (int j = 0; j < len-1-i; j++) {
            count++;
            if (n[j] > n[j + 1]) {
                int tmp = n[j];
                n[j] = n[j + 1];
                n[j + 1] = tmp;
                flag = false;
            }
        }
        for (auto x : n)
            cout << x << " " ;
        cout << endl;
        if (flag)    break;
    }
    cout << count << endl;
}

看,我們是不是少了很多次數,現在只需要比較15次了,而且大迴圈只進行了3次。

但是,我們再仔細看看上面的迴圈結果,發現後面3個數原本就是有序的,再怎麼比較,他們的位置已經是相對固定的了。那麼如何進行進一步優化呢?

如果我們知道有序區間的邊界位置就好了。對!那麼我們就設定一個邊界值。但是要怎麼設定?我們可以記錄每次交換的最後一個交換位置,就是有序與無序之間的邊界了。

void bsort(vector<int>& n) {
    int len = n.size();
    int count = 0;
    int bianjie = 0;       //記錄每次就換的位置
    int lastb = len-1;    //記錄有序區間邊界值
    for (int i = 0; i < len; i++) {
        bool flag = true;
        for (int j = 0; j < lastb; j++) {   //迴圈的條件是不超過無序區間的範圍
            count++;
            if (n[j] > n[j + 1]) {
                int tmp = n[j];
                n[j] = n[j + 1];
                n[j + 1] = tmp;
                bianjie = j;
                flag = false;
            }
        }
        for (auto x : n)
            cout << x << " " ;
        cout << endl;
        lastb = bianjie;     //每次最後交換的位置就是邊界值
        if (flag)    break;
    }
    cout << count << endl;
}

是的,我們的比較次數變成了9.真是太棒鳥~從21次慢慢減為9次。