[算法]快速排序之Partition的寫法

CLRS上的實現

//loop invariant 
/*
[0:i]是低區
[i+1:j]是高區, 本來屬於低區的就應該放到低區,同時把高區中的第一個換出來
*/
int clrs_partition(int* A, int left, int right){
    int i = left-1;
    int tmp = A[right]; //注意是從後面開始

    for (int j = left; j < right; j++){ //不是 <= 初始值是left,不是i
        if (A[j] < tmp){
            i++;
            //i這時候指向高區的第一個元素, j指向一個本來應該屬於低區的元素
            swap(A[i], A[j]);

        }
    }
    //sawp
    i++;
    swap(A[i],A[right]);
    //printArr()
    return i;
}

另外一種實現

//loop invariant:
//每次放入hole以前(能夠做爲一種方法,即不必定非要等循環結束再看invariant)
//[left:i-1] 的元素必定小於tmp
//[j-1:right] 的元素必定大於tmp
//移動i的時候 hole在j處(右邊就是高區)
//移動j的時候 hole在i處(左邊就是低區)
int my_partition(int* A, int left, int right){
    const int l = left;
    const int r = right;

    int tmp = A[left];
    int hole = left;
    int i = left;
    int j = right;
    bool toggle = false;
    while (i < j){ //注意這裏是 <=  !!!
        if (toggle)
        {
            if (A[i]>tmp){
                A[hole] = A[i]; //填上坑
                hole = i; //空出一個位置,放比tmp小的
                toggle = false;
            }
            else{ //注意這個else, 不能去掉,不然, 
                //若是去掉了, loop invariant 就變成了 [left:i-2]是低區, [j+2:right]是高區
                //移動i的時候 hole在j+1處(右邊就是高區)
                //移動j的時候 hole在i-1處(左邊就是低區)
                //i==j 退出循環的時候, hole , i(j) 或者 i(j),hole,。。。。有點亂。。
                i++;
            }
        }
        else
        {
            if (A[j] < tmp){
                A[hole] = A[j]; //填上坑
                hole = j;//空出一個位置,放比tmp大的
                toggle = true;
            }
            else
            {
                j--;
            }
        }
    }
    A[hole] = tmp;
    return hole;
}
相關文章
相關標籤/搜索