1.hoare版本
int PartSort1(int* a,int begin,int end)//hoare版本
{
int key = begin;//把第一个位置设成关键字
while (begin < end)
{
//从后面选比关键字小的,如果关键字小于末尾的数,end往前走
while (begin < end && a[key] <= a[end])
--end;
// 从前面选比关键字大的,如果关键字大于第一个数,begin就往后走
while (begin < end && a[key] >= a[begin])
++begin;
//交换begin和end
Swap(&a[begin], &a[end]);
}
//跳出循环时begin和end相遇,把第一个位置key的值换成此时begin的值
Swap(&a[begin], &a[key]);
return begin;
}
void QuickSort(int* a,int left,int right)
{
if (left >= right)
return;
else
{
int div = PartSort1(a, left, right);
//递归去div的左区间找新的关键字
QuickSort(a, left, div - 1);
//递归去div的右区间找新的关键字
QuickSort(a, div + 1, right);
}
}
hoare版本还可以进行优化
1).三数取中法
三数取中法选key(针对直接有序的数组)
int GetMidIndex(int* a, int begin, int end)
{
int mid = begin + ((end - begin) >> 1);
if (a[begin] < a[mid])
{
if (a[mid] < a[end])
{
return mid;
}
else if (a[begin]>a[end])
{
return begin;
}
else
{
return end;
}
}
else
{
if (a[mid] > a[end])
{
return mid;
}
else if (a[begin] < a[end])
{
return begin;
}
else
{
return end;
}
}
}
int PartSort(int* a, int begin, int end)
{
int mid = GetMidIndex(a, begin, end);
Swap(&a[begin], &a[mid]);
int key = begin;//把第一个位置设成关键字
while (begin < end)
{
//从后面选比关键字小的,如果关键字小于末尾的数,end往前走
while (begin < end && a[key] <= a[end])
--end;
//从前面选比关键字大的,如果关键字大于第一个数,begin就往后走
while (begin < end && a[key] >= a[begin])
++begin;
//交换begin和end
Swap(&a[begin], &a[end]);
}
//跳出循环时begin和end相遇,把第一个位置key的值换成此时begin的值
Swap(&a[begin], &a[key]);
return begin;
}
void QuickSort(int* a,int left,int right)
{
if (left >= right)
return;
else
{
int div = PartSort(a, left, right);
//递归去div的左区间找新的关键字
QuickSort(a, left, div - 1);
//递归去div的右区间找新的关键字
QuickSort(a, div + 1, right);
}
}
2).小区间优化
void QuickSort(int* a,int left,int right)
{
//小区间优化
if (left >= right)
return;
if ((right - left + 1) < 10)
{
InsertSort(a + left, right - left + 1);
}
else
{
int div = PartSort1(a, left, right);
//递归去div的左区间找新的关键字
QuickSort(a, left, div - 1);
//递归去div的右区间找新的关键字
QuickSort(a, div + 1, right);
}
}
2.挖坑法
int PartSort2(int* a, int begin, int end)//挖坑法
{
int key = a[begin];
while (begin < end)
{
while (begin < end && key <= a[end])
--end;
a[begin] = a[end];//此时begin=0;
while (begin < end && key >= a[begin])
++begin;
a[end] = a[begin];
}
//此时begin和end相遇
a[begin] = key;
return begin;
}
void QuickSort(int* a,int left,int right)
{
if (left >= right)
return;
else
{
int div = PartSort2(a, left, right);
//递归去div的左区间找新的关键字
QuickSort(a, left, div - 1);
//递归去div的右区间找新的关键字
QuickSort(a, div + 1, right);
}
}
3.前后指针版本
int PartSort3(int* a, int begin, int end)//前后指针版本
{
int key = a[begin];
int prev = begin;
int cur = begin + 1;
while (cur <= end)
{
//给定两个指针prev cur ,如果a[cur]>key cur继续往前走,当a[cur]<key时,
//先++prev,若此时prev不等于cur,就交换a[prev]和a[cur]
if (a[cur] < key && ++prev != cur)
{
Swap(&a[prev], &a[cur]);
}
++cur;
}
Swap(&key, &a[prev]);
return prev;
}
void QuickSort(int* a,int left,int right)
{
if (left >= right)
return;
else
{
int div = PartSort3(a, left, right);
//递归去div的左区间找新的关键字
QuickSort(a, left, div - 1);
//递归去div的右区间找新的关键字
QuickSort(a, div + 1, right);
}
}