本文目录
一、快速排序递归法
1.快速排序思想
2.hoare版本实现快速排序
//快速排序
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int keyi = left;
while (left < right)
{
//右边找小
while (left < right && a[right] >= a[keyi])
{
right--;
}
//左边找大
while (left < right && a[left] <= a[keyi])
{
left++;
}
Swap(&a[left], &a[right]);
}
Swap(&a[keyi], &a[left]);
QuickSort(a, begin, left - 1);
QuickSort(a, left + 1, end);
}
3.hoare版本的优化
1>使用随机值rand()函数
//快速排序
void QuickSort1(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int keyi = left;
int randi = left + rand() % (right - left);
Swap(&a[randi], &a[left]);
while (left < right)
{
//右边找小
while (left < right && a[right] >= a[keyi])
{
right--;
}
//左边找大
while (left < right && a[left] <= a[keyi])
{
left++;
}
Swap(&a[left], &a[right]);
}
Swap(&a[keyi], &a[left]);
QuickSort1(a, begin, left - 1);
QuickSort1(a, left + 1, end);
}
2>三数取中
int GetMidNumi(int* a, int left, int right)
{
int mid = (left + right) / 2;
if (a[left] < a[mid])
{
if (a[mid] < a[right])
{
return mid;
}
else if (a[left] < a[right])
{
return right;
}
else
{
return left;
}
}
else
{
if (a[left] < a[right])
{
return left;
}
else if (a[mid] < a[right])
{
return right;
}
else
{
return mid;
}
}
}
//快速排序:三数取中
void QuickSort2(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int keyi = left;
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
while (left < right)
{
//右边找小
while (left < right && a[right] >= a[keyi])
{
right--;
}
//左边找大
while (left < right && a[left] <= a[keyi])
{
left++;
}
Swap(&a[left], &a[right]);
}
Swap(&a[keyi], &a[left]);
QuickSort2(a, begin, left - 1);
QuickSort2(a, left + 1, end);
}
3>三路划分
4.证明hoare版本的key在左边,必须让右边先走
5.挖坑法实现快速排序
//快速排序:挖坑法
void QuickSort3(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int hole = left;
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
int key = a[left];
while (left < right)
{
//右边找小
while (left < right && a[right] >= key)
{
right--;
}
a[hole] = a[right];
hole = right;
//左边找大
while (left < right && a[left] <= key)
{
left++;
}
a[hole] = a[left];
hole = left;
}
a[hole] = key;
QuickSort3(a, begin, hole - 1);
QuickSort3(a, hole + 1, end);
}
6.将前面快排的一趟排序给提取出来
int PartSort1(int* a, int left, int right)
{
int keyi = left;
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
while (left < right)
{
//右边找小
while (left < right && a[right] >= a[keyi])
{
right--;
}
//左边找大
while (left < right && a[left] <= a[keyi])
{
left++;
}
Swap(&a[left], &a[right]);
}
Swap(&a[keyi], &a[left]);
return left;
}
int PartSort2(int* a, int left, int right)
{
int hole = left;
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
int key = a[left];
while (left < right)
{
//右边找小
while (left < right && a[right] >= key)
{
right--;
}
a[hole] = a[right];
hole = right;
//左边找大
while (left < right && a[left] <= key)
{
left++;
}
a[hole] = a[left];
hole = left;
}
a[hole] = key;
return hole;
}
//快速排序
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int keyi = PartSort2(a, left, right);
QuickSort(a, left, keyi - 1);
QuickSort(a, keyi + 1, right);
}
7.双指针法实现快速排序
int PartSort3(int* a, int left, int right)
{
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
int prev = left;
int cur = left + 1;
int key = a[left];
while (cur <= right)
{
if (a[cur] > key)
{
cur++;
}
else
{
prev++;
Swap(&a[prev], &a[cur]);
cur++;
}
}
Swap(&a[prev], &a[left]);
return prev;
}
//快速排序
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int keyi = PartSort3(a, left, right);
QuickSort(a, left, keyi - 1);
QuickSort(a, keyi + 1, right);
}
int PartSort3(int* a, int left, int right)
{
int midi = GetMidNumi(a, left, right);
Swap(&a[midi], &a[left]);
int prev = left;
int cur = left + 1;
int key = a[left];
while (cur <= right)
{
if (a[cur] < key && ++prev != cur)
Swap(&a[cur], &a[prev]);
cur++;
}
Swap(&a[prev], &a[left]);
return prev;
}
//快速排序
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
int keyi = PartSort3(a, left, right);
QuickSort(a, left, keyi - 1);
QuickSort(a, keyi + 1, right);
}
8.快速排序小区间优化
//快速排序
void QuickSort(int* a, int left, int right)
{
if (left >= right)
{
return;
}
if ((right - left + 1) > 10)
{
int keyi = PartSort3(a, left, right);
QuickSort(a, left, keyi - 1);
QuickSort(a, keyi + 1, right);
}
else
{
InsertSort(a + left, right - left + 1);
}
}
二、快速排序非递归
//快速排序非递归
void QuickSortNonR(int* a, int left, int right)
{
if (left >= right)
{
return;
}
Stack st;
StackInit(&st);
StackPush(&st, right);
StackPush(&st, left);
while (!StackEmpty(&st))
{
int begin = StackTop(&st);
StackPop(&st);
int end = StackTop(&st);
StackPop(&st);
int keyi = PartSort3(a, begin, end);
// [begin,keyi-1] keyi [keyi+1,end]
if (keyi + 1 < end)
{
StackPush(&st, end);
StackPush(&st, keyi + 1);
}
if (begin < keyi - 1)
{
StackPush(&st, keyi - 1);
StackPush(&st, begin);
}
}
StackDestroy(&st);
}
———————————————————————————————————————
好了本期内容就到这里了
如果对你有帮助的话,不要忘记点赞加收藏哦!!!