快速排序是Hoare于1962年提出的一种二叉树的交换排序方法。其基本思想为:任取待排序元素序列中的某元素为基准值,按照该排序码将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
快速排序是一种不稳定的排序,其时间复杂度为O(nlogn),空间复杂度为O(logn)
1.hoare版本
//hoare版本
int partition_1(int* ar, int left, int right)
{
int low = left;
int high = right - 1;
int key = ar[low];
while (low < high)
{
while (low<high && ar[high]>key)
high--;
Swap(&ar[low], &ar[high]);
while (low < high && ar[low] <= key)
low++;
Swap(&ar[low], &ar[high]);
}
return low;
}
void QuickSort_1(int* ar, int left, int right)
{
if (left >= right)
return;
int pos = partition_1(ar, left, right);
QuickSort_1(ar, left, pos);
QuickSort_1(ar, pos + 1, right);
}
2.挖坑法
将第一个数据先保存在临时变量key中,形成一个坑位。
//挖坑法
int partition_2(int* ar, int left, int right)
{
int low = left;
int high = right - 1;
int key = ar[low];
while (low < high)
{
while (low<high && ar[high]>key)
high--;
ar[low] = ar[high];
while (low < high && ar[low] <= key)
low++;
ar[high] = ar[low];
}
ar[low] = key;
return low;
}
void QuickSort_2(int* ar, int left, int right)
{
if (left >= right)
return;
int pos = partition_2(ar, left, right);
QuickSort_2(ar, left, pos);
QuickSort_2(ar, pos + 1, right);
}
3.前后指针法
//前后指针法
int partition_3(int* ar, int left, int right)
{
int key = ar[left];
int next = left;
for (int prev = next + 1; prev < right; prev++)
{
if (ar[prev] < key)
{
next++;
if (next != prev)
{
Swap(&ar[next], &ar[prev]);
}
}
}
Swap(&ar[left], &ar[next]);
return next;
}
void QuickSort_3(int* ar, int left, int right)
{
if (left >= right)
return;
int pos = partition_3(ar, left, right);
QuickSort_3(ar, left, pos);
QuickSort_3(ar, pos + 1, right);
}
4.三者取中法
//三者取中法
int GetMinIndex(int* ar, int left, int right)
{
int mid = (left + right - 1) / 2;
if (ar[left] < ar[mid] && ar[mid] < ar[right - 1])
return mid;
if (ar[left] > ar[mid] && ar[left] < ar[right - 1])
return left;
return right - 1;
}
int partition_4(int* ar, int left, int right)
{
int min_index = GetMinIndex(ar, left, right);
if (min_index != left)
Swap(&ar[left], &ar[min_index]);
int key = ar[left];
int next = left;
for (int prev = next + 1; prev < right; prev++)
{
if (ar[prev] < key)
{
next++;
if (next != prev)
{
Swap(&ar[next], &ar[prev]);
}
}
}
Swap(&ar[left], &ar[next]);
return next;
}
#define M 20
void QuickSort_4(int* ar, int left, int right)
{
if (left >= right)
return;
if (right - left <= M)
InsertSort(ar, left, right);
else
{
int pos = partition_4(ar, left, right);
QuickSort_4(ar, left, pos);
QuickSort_4(ar, pos + 1, right);
}
}