说明快速排序法(quick sort)是目前所公认最快的排序方法之一(视解题的对象而定),虽然
快速排序法在最差状况下可以达O(n2),但是在多数的情况下,快速排序法的效率表现是相当不
错的。
快速排序法的基本精神是在数列中找出适当的轴心,然后将数列一分为二,分别对左边与右边
数列进行排序,而影响快速排序法效率的正是轴心的选择。
这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解,
也最符合轴心分割与左右进行排序的概念,适合对初学者进行讲解。
解法这边所介绍的快速演算如下:将最左边的数设定为轴,并记录其值为s
廻圈处理:
令索引i 从数列左方往右方找,直到找到大于s 的数
令索引j 从数列左右方往左方找,直到找到小于s 的数
如果i >= j,则离开回圈
如果i < j,则交换索引i与j两处的值
将左侧的轴与j 进行交换
对轴左边进行递回
对轴右边进行递回
透过以下演算法,则轴左边的值都会小于s,轴右边的值都会大于s,如此再对轴左右两边进行
递回,就可以对完成排序的目的,例如下面的实例,*表示要交换的数,[]表示轴:
[41] 24 76* 11 45 64 21 69 19 36*
[41] 24 36 11 45* 64 21 69 19* 76
[41] 24 36 11 19 64* 21* 69 45 76
[41] 24 36 11 19 21 64 69 45 76
21 24 36 11 19 [41] 64 69 45 76
在上面的例子中,41左边的值都比它小,而右边的值都比它大,如此左右再进行递回至排序完
快速排序
快速排序法在最差状况下可以达O(n2),但是在多数的情况下,快速排序法的效率表现是相当不
错的。
快速排序法的基本精神是在数列中找出适当的轴心,然后将数列一分为二,分别对左边与右边
数列进行排序,而影响快速排序法效率的正是轴心的选择。
这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解,
也最符合轴心分割与左右进行排序的概念,适合对初学者进行讲解。
解法这边所介绍的快速演算如下:将最左边的数设定为轴,并记录其值为s
廻圈处理:
令索引i 从数列左方往右方找,直到找到大于s 的数
令索引j 从数列左右方往左方找,直到找到小于s 的数
如果i >= j,则离开回圈
如果i < j,则交换索引i与j两处的值
将左侧的轴与j 进行交换
对轴左边进行递回
对轴右边进行递回
透过以下演算法,则轴左边的值都会小于s,轴右边的值都会大于s,如此再对轴左右两边进行
递回,就可以对完成排序的目的,例如下面的实例,*表示要交换的数,[]表示轴:
[41] 24 76* 11 45 64 21 69 19 36*
[41] 24 36 11 45* 64 21 69 19* 76
[41] 24 36 11 19 64* 21* 69 45 76
[41] 24 36 11 19 21 64 69 45 76
21 24 36 11 19 [41] 64 69 45 76
在上面的例子中,41左边的值都比它小,而右边的值都比它大,如此左右再进行递回至排序完
成。
随机排序
void Shuffle(int* &pData, int num, int seed)
{
srand(seed);
int nTemp;
for (int i = 0; i < num; i ++)
{
int j = (double) rand() / (RAND_MAX + 1) * num;
nTemp = pData[j];
pData[j] = pData[i];
pData[i] = nTemp;
}
}
快速排序
void QuickSort_1(int* &pData, int num)
{
int nBase = pData[0];
QuickSort_1_Recursion(pData, nBase, 0, num - 1);
}
bool QuickSort_1_Recursion(int* &pData, int baseDat, int nStart, int nEnd)
{
bool bGetMax = false;
bool bGetMin = false;
int oldEnd = nEnd;
while(nStart < nEnd)
{
if (pData[nStart + 1] < baseDat)
{
nStart ++;
}
else
{
bGetMax = true;
}
if (pData[nEnd - 1] > baseDat)
{
nEnd --;
}
else
{
bGetMin = true;
}
if (bGetMax && bGetMin)
{
int nTemp;
nTemp = pData[nStart];
pData[nStart] = pData[nEnd];
pData[nEnd] = nTemp;
bGetMax = false;
bGetMin = false;
}
}
// 左边序列
if (nStart < nEnd)
{
QuickSort_1_Recursion(pData, pData[nStart], nStart, nEnd);
}
// 右边序列
if (nEnd + 1 < oldEnd)
{
QuickSort_1_Recursion(pData, pData[nEnd + 1], nEnd+1, oldEnd);
}
return true;
}