快速排序顾名思义是目前实践中最快的排序算法。如归并排序算法一样,快速排序算法也使用了分治的递归思想。快速排序的思想:选取枢纽元,同过枢纽元对数据进行分割,左边的数据小于枢纽元,右边的数据大于枢纽元。然后利用分治递归的思想,对左右数据进行分割,最后进行合并。枢纽元的选取对快速排序非常重要!!
怎么选取枢纽元呢?有的人会说选第一个或者最后一个数据。可以这样选择。但是如果出现第一个数据或者最后一个数据是最小的数据,那么其快速排序的效率将到达最低。那么就随机选择枢纽元吧!当然可以啊,但是随机数的生成需要借助随机数发生器和引擎,其代价相当高,最终也会导致快速排序的效率降低。综上所述,我们使用三数中值法来选取枢纽元。三数中值分割法的思想:选择左端(Left),右端(Right),中间值(Center)的中值为枢纽元。
HubElem Median(int arrays[], int left, int right) {
auto center = (left + right) / 2;
if (arrays[left] > arrays[center])
std::swap(arrays[left], arrays[center]);
if (arrays[left] > arrays[right])
std::swap(arrays[left], arrays[right]);
if (arrays[center] > arrays[right])
std::swap(arrays[center], arrays[right]);
std::swap(arrays[center], arrays[right - 1]);
return arrays[right - 1];
}
#include<iostream>
const int Cutoff = 3;
typedef int HubElem;
HubElem Median(int* arrays, int left, int right) {
auto center = (left + right) / 2;
if (arrays[left] > arrays[center])
std::swap(arrays[left], arrays[center]);
if (arrays[left] > arrays[right])
std::swap(arrays[left], arrays[right]);
if (arrays[center] > arrays[right])
std::swap(arrays[center], arrays[right]);
std::swap(arrays[center], arrays[right - 1]);
return arrays[right - 1];
}
void InsertionSort(int* arrays, int N) {
for (int i = 1; i < N; ++i) {
int j = 0;
auto temp = arrays[i];
for (j = i; j > 0 && arrays[j - 1] > temp; --j)
arrays[j] = arrays[j - 1];
arrays[j] = temp;
}
}
void QuickSort(int* arrays, int left, int right) {
if (left + Cutoff <= right) {
auto pivot = Median(arrays, left, right);
auto i = left;
auto j = right - 1;
while (true) {
while (arrays[++i] < pivot);
while (arrays[--j] > pivot);
if (i < j)
std::swap(arrays[i], arrays[j]);
else
break;
}
std::swap(arrays[i], arrays[right - 1]);
QuickSort(arrays, left, i - 1);
QuickSort(arrays, i + 1, right);
}
else
InsertionSort(arrays + left, right - left + 1);
}
int main(void)
{
int arrays[] = { 1,4,7,2,5,8,3,6,9,10,12,45,78,13,16,52,26 };
QuickSort(arrays, 0, sizeof(arrays) / sizeof(arrays[0]) - 1);
for (const auto& x : arrays) {
std::cout << x << std::endl;
}
}
总结:1.本来想用vector代替数组的,结果会发生越界。vector是自动伸缩的数组,会导致其size无限大。求大佬帮我解决这个问题。
2.当数据的大小小于10时,插入排序或者希尔排序要比快速排序效率高。