氣泡排序與改進
阿新 • • 發佈:2020-12-06
這個是參考大部分博主的,我想自己記下來
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次。