改進冒泡排序法


1. 問題

學過編程的朋友應該對冒泡排序不陌生,這里就不多講了,直接提一個有意思的問題:

冒泡排序中,如果經過某一趟冒泡排序后,該序列已經排序好了,那么此時就可以提前退出了。

 

2. 分析

2.1 如何判斷序列已經是有序的呢?

看一個有序數列{1, 2, 3, 4, 5},如果用冒泡法來排序,我們發現一趟冒泡沉底過程中,是不會發生任何交換的,因為每個數an都比an+1小,所以如果一趟冒泡沉底過程中,沒有發生過交換,那么這個序列就是有序的

2.2 如果只發生一次交換呢?

假設:如果一趟冒泡沉底過程中,只發生一次沉底交換,那么這次交換完畢后,這個序列是有序的

證明:

設只在ax處發生了一次交換,那么根據2.1的結論,a1~ax的序列就一定是有序的,交換后,而且ax+1~an的序列也是有序的,而ax和ax+1交換后也是有序的,

但如果ax+1小於x前面的任何一個數,則該數列仍然是無序的,如{1, 4, 5, 3, 6, 7},第一趟沉底過程中只需交換5和3一次,但交換后數列為{1, 4, 3, 5, 6, 7},仍然是無序的

 

3. code

//Improve bubble sort
//When it do not need to change any number in one bubble sort, all the sequence sort completely
int ImproveBubbleSort(int nSequenceArray[], int nSize)
{
    int nTime = 0;
    for (int i = nSize - 1; i > 0 ; i--)
    {
        int    nExchanged = 0;
        for (int j = 0; j < i; j++)
        {
            if (nSequenceArray[j] > nSequenceArray[j + 1])
            {
                int nTemp = nSequenceArray[j];
                nSequenceArray[j] = nSequenceArray[j + 1];
                nSequenceArray[j + 1] = nTemp;
                nExchanged++;
            }

            nTime++;
        }

        if (nExchanged <= 0)
        {
            break;
        }
    }

    return    nTime;
}


void    Test()
{
    int nSequenceArray[] = {2, 8, 19, 3, 4, 7, 11, 37, 5, 4};
    //int nSequenceArray[] = {11, 3, 5, 7, 37, 4, 19, 8, 2, 4};
    int nSize = sizeof(nSequenceArray) / sizeof(nSequenceArray[0]);

    int nTime = ImproveBubbleSort(nSequenceArray, nSize);
    printf("After sort %d times, the sequence is : ", nTime);
    for (int i = 0; i < nSize; i++)
    {
        printf("%d, ", nSequenceArray[i]);
    }
}

 

4. 結果

4.1 未優化的冒泡排序(循環45次)

No Improve

4.2 以交換次數為0作為退出條件的冒泡排序(循環42次)

Improve_0

改進后的冒泡排序,在數列本身有一定的順序的情況下,是可以顯著提高排序效率的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM