快排递归框架:
void QuickDSort(int* array, int left, int right)
{
if (right - left > 1)
{
int div = partion(array, left, right);
QuickDSort(array, left, div);
QuickDSort(array, div + 1, right);
}
}
划分区间:
先想办法拿到一个基准值,进而才可以划分,但是直接把right-1的位置的元素作为基准值有可能极端情况下性能爆炸差,所以引入特殊的取值方法
三值取中法:
顾名思义,就是取三个值,选出一个中间值作为基准值,能极大程度避免取的基准值太极端
a b,如果c比a还小,那a就是中间值
a b,如果c比b还大,那b就是中间值
如果都不是,说明c就是中间值
b a,情况同上处理
int GetMidIndex(int* array, int left, int right)
{
int mid = left + ((right - left) >> 1);
//a b
if (array[left] < array[right - 1])
{
//c<a ,a就是mid
if (array[mid] < array[left])
{
return left;
}
//c>b,b就是mid
else if (array[mid]>array[right - 1])
{
return right - 1;
}
else
{
return mid;
}
}
else
{
//b a,c<b,b就是mid
if (array[mid] < array[right - 1])
{
return right - 1;
}
//b a,c>a,a就是mid
else if (array[mid]>array[left])
{
return left;
}
else
{
return mid;
}
}
}
取好基准值之后,就可以进行元素的比较了,把左侧元素调整为都比基准值小,右侧都比基准值大
比较方法:
定义两个指针,一个在前,一个在后,因为对数组操作,所以可以用数组下标代替
begin从前找比基准值大的元素,没有就begin++,直到找到
end同理,从后找比基准值小的元素,没有就end–,直到找到
找到的话,begin和end的位置如果不一样,就交换元素
最终将基准值放好(因为一开始把基准值和right-1位置的元素互换了)
要和right-1位置换,因为end是变化的
int partion(int* array, int left, int right)
{
int mid = GetMidIndex(array, left, right);
swap(array[mid], array[right - 1]);
int begin = left;
int end = right - 1;
int key = array[right - 1];
while (begin<end)
{
//从左往右找比基准值大的元素
while (begin < end&&array[begin] <= key)
{
begin++;
}
//从右往左找比基准值小的元素
while (begin < end&&array[end] >= key)
{
end--;
}
//找到之后
if (begin != end)
{
swap(array[begin], array[end]);
}
}
//放置基准值
if (begin != right - 1)
{
swap(array[begin], array[right - 1]);
}
return begin;
}