排序之冒泡排序

冒泡排序是一種交換排序。
什麼是交換排序呢?
交換排序:兩兩比較待排序的關鍵字,並交換不滿足次序要求的那對數,直到整個表都滿足次序要求爲止。

算法思想它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。
這個算法的名字由來是因爲越小的元素會經由交換慢慢“浮”到數列的頂端,故名。
假設有一個大小爲 N 的無序序列。冒泡排序就是要每趟排序過程中通過兩兩比較,找到第 i 個小(大)的元素,將其往上排。
這裏寫圖片描述

以上圖爲例,演示一下冒泡排序的實際流程:
假設有一個無序序列 { 4. 3. 1. 2, 5 }
第一趟排序:通過兩兩比較,找到第一小的數值 1 ,將其放在序列的第一位。
第二趟排序:通過兩兩比較,找到第二小的數值 2 ,將其放在序列的第二位。
第三趟排序:通過兩兩比較,找到第三小的數值 3 ,將其放在序列的第三位。
至此,所有元素已經有序,排序結束。

要將以上流程轉化爲代碼,我們需要像機器一樣去思考,不然編譯器可看不懂。
假設要對一個大小爲 N 的無序序列進行升序排序(即從小到大)。
(1) 每趟排序過程中需要通過比較找到第 i 個小的元素。
所以,我們需要一個外部循環,從數組首端(下標 0) 開始,一直掃描到倒數第二個元素(即下標 N - 2) ,剩下最後一個元素,必然爲最大。
(2) 假設是第 i 趟排序,可知,前 i-1 個元素已經有序。現在要找第 i 個元素,只需從數組末端開始,掃描到第 i 個元素,將它們兩兩比較即可。
所以,需要一個內部循環,從數組末端開始(下標 N - 1),掃描到 (下標 i + 1)。

//基本的冒泡排序代碼
void BubbleSort(int *a,int length)
{
    int temp = 0;
    for(int i = 0; i < length - 1; i++)
    {
        for(j = length -1; j > i; j--)
        {
            if(a[j - 1] > a[j])
            {
                temp = a[j - 1];
                a[j - 1] = a[j];
                a[j] = temp;
            }
        }
    }
}

對冒泡排序常見的改進方法是加入標誌性變量exchange,用於標誌某一趟排序過程中是否有數據交換。

如果進行某一趟排序時並沒有進行數據交換,則說明所有數據已經有序,可立即結束排序,避免不必要的比較過程。

//冒泡算法優化

void BubbleSort(int *a,int length)
{
    int temp = 0; // 用於交換的臨時變量
    int flag = false; //交換標誌
    for(int i = 0; i < length - 1; i++)
    {
        flag = false;
        //// 從後向前依次的比較相鄰兩個數的大小,遍歷一次後,把數組中第i小的數放在第i個位置上
        for(int j = length - 1; j > i; j--)
        {
        // 比較相鄰的元素,如果前面的數大於後面的數,則交換
            if(a[j - 1] > a[j])
            {
                temp = a[j - 1];
                a[j - 1] = a[j];
                a[j] = temp;
                flag = true;
            }
             // 如果標誌爲false,說明本輪遍歷沒有交換,已經是有序數列,可以結束排序
            if(false == flag)
            {
                break;
            }
        }
}
發佈了106 篇原創文章 · 獲贊 18 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章