排序算法(一)冒泡排序算法1

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;
}











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章