这是最初版本的和随机版本的结合,我也修改了一下最初版本的小点东西,思路还是最初版的思路,只是我把分割符中的数据排好了而已。呵呵。。也没有什么号说的。奉上源代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//化分区间,找到最后元素的排序位置。并返回分隔的点(即最后一数据排序的位置)。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
int i = nBeging + rand()%(nBeging - nEnd);
//这里是和hoare的思路写的,和原版本不是完全一样,思路是一样的。
int x = pData[i];
pData[i] = pData[nBeging];
pData[nBeging] = x;
//int x = pData[nBeging];
--nEnd;
while (nBeging < nEnd)
{
//从后向前,找到比X小的元素位置
while(pData[nEnd] > x)
{
--nEnd;
}
//把x小的元素位置提前,nBegin处刚好能保存比x小的元素
if (nBeging < nEnd)
{
pData[nBeging] = pData[nEnd];
pData[nEnd] = x; //这里是为了做一个哨兵,防止小区域增加时越界。
++nBeging;
}
//小的区域增加,找到一个不比x小的元素。
while (pData[nBeging] < x)
{
++nBeging;
}
//把不比x小的元素存放在大的区域内。nEnd刚好预留了此位置。
if (nBeging < nEnd)
{
pData[nEnd] = pData[nBeging];
--nEnd;
}
}
pData[nBeging] = x; //这里一定要赋值,不然如果是nEnd退出循环,他是保存着以前的大值,会出错。
return nBeging; //返回nD的位置,就是分割的位置。
}
//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
if (nBeging >= nEnd -1) //如果区域不存在或只有一个数据则不递归排序
{
return 1;
}
//这里因为分割的时候,分割点处的数据就是排序中他的位置。
//也就是说他的左边的数据都小于等于他,他右边的数据都大于他。
//所以他不在递归调用的数据中。
int i = Partition(pData, nBeging, nEnd); //找到分割点
QuickSortRecursion(pData, nBeging, i); //递归左边的排序
QuickSortRecursion(pData, i + 1, nEnd); //递归右边的排序
return 1;
}
//快速排序
int QuickSort(int* pData, int nLen)
{
srand((unsigned int)time(NULL));
//递归调用,快速排序。
QuickSortRecursion(pData, 0, nLen);
return 1;
}
int main()
{
int nData[10] = {2,6,3,4,1,5,7,8,10,9}; //测试数据
QuickSort(nData, 10);
for (int i = 0; i < 10; ++i)
{
printf("%d ", nData[i]);
}
printf("\n");
system("pause");
return 0;
}