1、冒泡排序的概念網上一大堆,這裏也就不復制了。下面主要是我的一些理解,算是在此做個筆記吧!
注:排序算法系列文章,採用VS2010編寫示例代碼
2、“冒泡”是一個很形象的比喻,下面先看一段簡單的代碼:
int nNum[] = {1, 3, 8, 5, 7, 6, 9, 2, 0, 8}; int nCount = sizeof (nNum) / sizeof (nNum[0]); int nMax = nNum[0]; for ( int i = 1; i < nCount; i++) { nMax = nMax > nNum[i] ? nMax : nNum[i]; } |
這段代碼很簡單,運行的結果是找出一組數中的最大值,執行完後nMax應該等於9;
3、根據上述代碼,那麼要實現排序,即將一組數由大到小(降序)排列或是由小到大(升序)排列,只要重複上述代碼就可以了。具體如下(以找出大值爲例):
(1)從一組數中找出最大的數,並保存,執行步驟(2);
(2)將(1)中找出的數從這組數中剔除,執行步驟(3);
(3)判斷這組數的個數是否小於2,若否,則執行(1),若是,則確定大小完成,執行(4);
(4)根據要求(升序還是降序)給出結果;
注意:如果待排序數原有n個,那麼找出最大值的操作要執行n-1次;
4、上述邏輯算法有了,但是在實現(2)的時候遇到了問題,如何真正移除一個數組中的元素?這個問題顯然不是一兩句話能說清楚的,這裏就換一種實現方式:爲了簡便,將待排序數放入vector中。
5、實現代碼如下(貌似有點繞):
// Bubble_Sort_Test.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <vector> using namespace std; int _tmain( int argc, _TCHAR* argv[]) { // 待排序的數 int nNum[] = {1, 3, 8, 5, 7, 6, 9, 2, 0, 8}; // 待排序數的個數 const int nCount = sizeof (nNum) / sizeof (nNum[0]); // 用vector保存待排序數 vector < int > vectorNum; for ( int i = 0; i < nCount; i++) { vectorNum.push_back( nNum[i] ); } // 用於保存排序結果 int nSort[nCount] = {-1}; // 排序 for ( int i = 0; i < nCount - 1; i++) // nCount個數,需要求最大值nCount-1次 { int nMax = vectorNum[0]; int nPos = 0; // 求最大值 for (unsigned int j = 1; j < vectorNum.size(); j++) { nMax = nMax > vectorNum[j] ? nMax : vectorNum[j]; nPos = nMax == vectorNum[j] ? j : nPos; // 保存最大值在vector中的位置,以便刪除 } nSort[i] = nMax; // 保存 vectorNum.erase(vectorNum.begin() + nPos); // 剔除最大值 } // 最後一個數的操作 nSort[nCount - 1] = *vectorNum.begin(); vectorNum.clear(); // 打印 for ( int i = 0; i < nCount; i++) { cout << nSort[i] << endl; } getchar (); return 0; } |
6、上述過程略顯複雜,但是思路卻是冒泡算法的基礎,實際上冒泡算法也是這樣一次一次求最大值,只不過這個求的過程中有一個巧妙的地方:它把一趟求最大值的過程,實現爲一趟兩兩交換的過程,最大值自然地被換到了數組的末尾。以{1, 3, 8, 5, 7, 6, 9, 2, 0, 8}爲例:
通過以上9次大小比較,進而交換位置,最後將最大值放到的末尾。
7、根據上述示例,可以這樣實現一個排序算法:
(1)從一組數中找出最大的數:通過交換位置,將其放到末尾(這一過程就是冒一次泡),執行步驟(2);
(2)將這組數的個數減1,執行步驟(3);
(3)若冒泡次數小於待排序數的個數減1,執行(1);否則,排序完成。
注意:如果待排序數原有n個,那麼要冒泡n-1次;而如果每次冒泡需要交換數據的個數爲m,則需要交換m-1次。
8、實現代碼:
int _tmain( int argc, _TCHAR* argv[]) { // 待排序的數 int nNum[] = {1, 3, 8, 5, 7, 6, 9, 2, 0, 8}; // 待排序數的個數 const int nCount = sizeof (nNum) / sizeof (nNum[0]); // 冒泡排序 for ( int i = 0; i < nCount - 1; i++) // nCount個數,冒泡nCount-1次 { for ( int j = 0; j < nCount - 1 - i; j++) // i等於幾就表示最後i個數已經確定了,對nCount-1-i個數進行交換,找出最大值 { if (nNum[j] > nNum[j + 1]) // 大的放到後面 { int nTemp = nNum[j + 1]; nNum[j + 1] = nNum[j]; nNum[j] = nTemp; } cout << nNum[j]; } cout << endl; } // 輸出結果 for ( int i = 0; i < nCount; i++) { cout << nNum[i]; } getchar (); return 0; } |