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