經典排序算法的設計與實現

理解技巧:
代碼中遇到while(){}循環時,先考慮跳過循環的情況(即不滿足判斷條件的情況),以達到簡化代碼的目的。這樣反而能幫助理解while(){}循環的作用。

關注變量在程序中是否發生變化(或者說有沒有被賦值):沒有發生,則說明此變量是用來保存重要數據的;發生了,則留心發生了幾次變化,分別在哪行執行的。

使用索引是爲了遍歷。

%取最後一位的數字,/取第一位上的數字。

“++”運算符被稱爲自增運算符。如果“++”運算符出現在變量的前面(++var),那麼在表達式使用變量之前,變量的值將增加1。如果“++”運算符出現在變量之後(var++),那麼先對錶達式求值,然後變量的值才增加1。同理自減運算。

保存一下堆排序的算法

void HeapAdjust(Sqlist &L, int s, int m)
{//調整L.key[s]使L.key[s....m]成爲一個大頂堆
    int rc, j;
    rc = L.key[s];  //97
    for (j = 2 * s; j <= m; j *= 2)
    {
        if (j<m&&L.key[j]<L.key[j + 1]) j++;   //這一句的判斷,保證j爲,兩個子樹上key較大的記錄的下標(如果是兩顆子樹的話)
        if (!(rc<L.key[j])) break;  //注意:優先級問題,須在!後加括號
        L.key[s] = L.key[j]; s = j;
    }
    L.key[s] = rc;
}

void HeapSort(Sqlist &L)
{//堆排序。時間複雜度爲O(nlog2n)
    int i;
    for (i = L.length / 2; i > 0; i--)
        HeapAdjust(L, i, L.length);   //將L.key[1...L.length]建成大頂堆
    for (i = L.length; i>1; i--)
    {
        SWAP(L.key[1], L.key[i]);  //最後一個記錄相互交換
        HeapAdjust(L, 1, i - 1);   //將L.key[1...i-1]重新調整爲大頂堆
    }
}

這裏有個巨大的bug,內存中的length似乎被 L.key[s] = rc賦值的時候直接被覆蓋了。

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