// 单向扫描就地重排
int Partitation_1Way(int array[], int nIdxLeft, int nIdxRight)
{
assert(NULL != array);
if (nIdxLeft == nIdxRight)
return nIdxLeft;
// Take the last element as middle value.
int nMiddleVal = array[nIdxRight];
int nIdxSmall = nIdxLeft - 1;
// Always true in loop:
// elements within [nIdxLeft, nIdxSmall] are smaller than nMidVal.
// elements within [nIdxSmall+1, nIdxBig] are bigger than nMidVal.
for (int nIdxBig = nIdxLeft; nIdxBig<=nIdxRight; nIdxBig++)
{
if (array[nIdxBig]<=nMiddleVal)
{
nIdxSmall ++;
if (nIdxSmall != nIdxBig)
{
int nTemp = array[nIdxSmall];
array[nIdxSmall] = array[nIdxBig];
array[nIdxBig] = nTemp;
}
}
}
return nIdxSmall;
}
// 双向扫描就地重排
int Partitation_2Way(int array[], int nIdxLeft, int nIdxRight)
{
assert(NULL != array);
if (nIdxLeft == nIdxRight)
return nIdxLeft;
// Take the first element as middle value.
int nMidVal = array[nIdxLeft];
int nIdxBackward = nIdxLeft;
int nIdxForward = nIdxRight;
for ( ; nIdxBackward < nIdxForward; )
{
// forward find the small one from tail, move front
while (nIdxBackward < nIdxForward && array[nIdxForward] > nMidVal)
nIdxForward--;
array[nIdxBackward] = array[nIdxForward];
// backward find the big one from head, move back.
while (nIdxBackward < nIdxForward && array[nIdxBackward] < nMidVal)
nIdxBackward++;
array[nIdxForward] = array[nIdxBackward];
}
array[nIdxBackward] = nMidVal;
return nIdxBackward;
}
void QuickSort(int array[], int nIdxLeft, int nIdxRight)
{
if (NULL == array || nIdxLeft == nIdxRight)
return;
if (nIdxLeft < nIdxRight)
{
int nIdxMid = Partitation_1Way(array, nIdxLeft, nIdxRight);
//int nIdxMid = Partitation_2Way(array, nIdxLeft, nIdxRight);
QuickSort(array, nIdxLeft, nIdxMid-1);
QuickSort(array, nIdxMid+1, nIdxRight);
}
}