//交换函数
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//Hoare大佬原始版本
void QuickSort1(int* arr, int left , int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int keyi = left;
while (left < right)
{
while (left < right && arr[right] >= arr[keyi])
{
right--;
}
while (left < right && arr[left] <= arr[keyi])
{
left++;
}
Swap(arr + left, arr + right);
}
Swap(arr + left, arr + keyi);
keyi = left;
QuickSort1(arr, begin, keyi - 1);
QuickSort1(arr, keyi + 1, end);
}
//Hoare大佬原始版本+随机数选key优化
void QuickSort2(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int randi = left + rand() % (right - left);
Swap(arr + randi, arr + left);
int keyi = left;
while (left < right)
{
while (left < right && arr[right] >= arr[keyi])
{
right--;
}
while (left < right && arr[left] <= arr[keyi])
{
left++;
}
Swap(arr + left, arr + right);
}
Swap(arr + left, arr + keyi);
keyi = left;
QuickSort2(arr, begin, keyi - 1);
QuickSort2(arr, keyi + 1, end);
}
//Hoare大佬原始版本+三数取中选key优化
int GetMidNumi(int* arr, int left, int right)
{
int mid = (left + right) / 2;
if (arr[mid] < arr[right])
{
if (arr[left] < arr[mid])
{
return mid;
}
else //arr[left]>arr[mid]
{
return arr[left] < arr[right] ? left : right;
}
}
else
{
if (arr[right] > arr[left])
{
return right;
}
else
{
return arr[left] < arr[mid] ? left : mid;
}
}
}
void QuickSort3(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int midi = GetMidNumi(arr, left, right);
Swap(arr + midi, arr + left);
int keyi = left;
while (left < right)
{
while (left < right && arr[right] >= arr[keyi])
{
right--;
}
while (left < right && arr[left] <= arr[keyi])
{
left++;
}
Swap(arr + left, arr + right);
}
Swap(arr + left, arr + keyi);
keyi = left;
QuickSort3(arr, begin, keyi - 1);
QuickSort3(arr, keyi + 1, end);
}
//挖坑法+默认三数取中选key优化
void QuickSort4(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int midi = GetMidNumi(arr, left, right);
Swap(arr + midi, arr + left);
int key = arr[left];
int hole = left;
while (left < right)
{
while (left < right && arr[right] >= key)
{
right--;
}
arr[hole] = arr[right];
hole = right;
while (left < right && arr[left] <= key)
{
left++;
}
arr[hole] = arr[left];
hole = left;
}
arr[hole] = key;
QuickSort4(arr, begin, hole - 1);
QuickSort4(arr, hole + 1, end);
}
//前后指针法+默认三数取中选key优化
void QuickSort5(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
int begin = left;
int end = right;
int midi = GetMidNumi(arr, left, right);
Swap(arr + midi, arr + left);
int keyi = left;
int prev = left;
int cur = prev + 1;
while (cur <= right)
{
if (arr[cur] < arr[keyi])
{
prev++;
Swap(arr + prev, arr + cur);
}
cur++;
}
Swap(arr + prev, arr + keyi);
keyi = prev;
QuickSort5(arr, begin, keyi - 1);
QuickSort5(arr, keyi + 1, end);
}
//前后指针法(默认三数取中选key优化)+小区间优化
void InsertSort(int* arr, int n)
{
for (int i = 0; i < n - 1; i++)
{
int end = i;
int tmp = arr[end + 1];
while (end >= 0)
{
if (arr[end] > tmp)
{
arr[end + 1] = arr[end];
end--;
}
else
{
break;
}
}
arr[end + 1] = tmp;
}
}
void QuickSort(int* arr, int left, int right)
{
if (left >= right)
{
return;
}
if (right - left + 1 <= 10)
{
InsertSort(arr + left, right - left + 1);
return;
}
int begin = left;
int end = right;
int midi = GetMidNumi(arr, left, right);
Swap(arr + midi, arr + left);
int keyi = left;
int prev = left;
int cur = prev + 1;
while (cur <= right)
{
if (arr[cur] < arr[keyi])
{
prev++;
Swap(arr + prev, arr + cur);
}
cur++;
}
Swap(arr + prev, arr + keyi);
keyi = prev;
QuickSort(arr, begin, keyi - 1);
QuickSort(arr, keyi + 1, end);
}
递归改成非递归有两种方式:1. 直接改成循环。2. 使用栈辅助改循环
#include "Stack.h"
void QuickSortNonR(int* arr, int left, int right)
{
ST stack;
STInit(&stack);
STPush(&stack, right);
STPush(&stack, left);
while (!STEmpty(&stack))
{
int begin = STTop(&stack);
STPop(&stack);
int end = STTop(&stack);
STPop(&stack);
if (begin >= end)
{
continue;
}
int midi = GetMidNumi(arr, begin, end);
Swap(arr + midi, arr + begin);
int keyi = begin;
int prev = begin;
int cur = prev + 1;
while (cur <= end)
{
if (arr[cur] < arr[keyi])
{
prev++;
Swap(arr + prev, arr + cur);
}
cur++;
}
Swap(arr + keyi, arr + prev);
keyi = prev;
STPush(&stack, end);
STPush(&stack, keyi + 1);
STPush(&stack, keyi - 1);
STPush(&stack, begin);
}
STDestroy(&stack);
}