快速排序
快速排序可以由Hoare法、挖坑法、前后指针法三种方法完成,其中Hoare法的核心思想为:选取数组最左值作为KEY,然后让数组最右边的标记点(记作end)先走(从右往左走)直到找到第一个小于KEY的数组,然后让让数组最左边的标记点(记作begin)往右走,直到找到第一个大于KEY的数字,然后将以上找到的两个数字进行交换,重复上述过程,直到两个标记点相遇(因为两个标记点走的步长为一,故标记点一定相遇)最后在相遇点,将KEY的值置于此处,新得数组从此处向左一定都小于KEY值,向右一定大于KEY值,然后以begin到KEY-1与KEY+1到end划分为两个区间分别进行递归,直begin>end为主递归结束,此时递归返回数组为有序数组,过程如下图所示
第一趟完成后的数字如下图所示:
6左边都小于6,右边都大于6,接着就是以6左边作为一个区间和6右边作为一个区间,分别重复上述过程,完成对数组的排序过程,Hoare法代码如下所示:
void Swap(int* p, int* q)
{
int tmp = *p;
*p = *q;
*q = tmp;
}
int Part1Sort(int* a, int begin, int end)
{
int Mid = GetMidIndex(a, begin, end);
Swap(&a[Mid], &a[begin]);
int left = begin;
int right = end;
int keyi = left;
while (left < right)
{
while (a[right] >= a[keyi]&&left<right)
{
--right;
}
while (a[left] <= a[keyi]&&left<right)
{
++left;
}
Swap(&a[left], &a[right]);
}
Swap(&a[right],&a[keyi]);
keyi = left;
return keyi;
}
void QuickSort(int *a,int begin,int end)
{
if (begin >= end)
{
return;
}
if (end - begin > 10)
{
int keyi = Part1Sort(a,begin,end);
//int keyi = Part2Sort(a, begin, end);
//int keyi = Part3Sort(a, begin, end);
QuickSort(a, begin, keyi - 1);
QuickSort(a, keyi + 1, end);
}
else
{
//不一定是最开始的十个数,有可能是中间的十个数,故a+begin
InserSort(a+begin,end-begin+1);
}
}
void TestQuickSort()
{
int a[] = { 1,2,9,4,6,5,3,7,8 ,-1,-5,15,20,25,100,111};
int n = sizeof(a) / sizeof(int);
QuickSort(a,0,n-1);
PrintArray(a, n);
}
后续继续分享快速排序的其余两种方法。