快速排序
简单快排
快速排序(Quick Sort)也叫做分区排序,是目前应用最广泛的排序算法。在C++标准库中的排序程序就被称作qsort
,因为快速排序是其实现中的最基本算法。是一种不稳定的算法。
经过上面的图解,相信聪明的你们已经明白了快排的奥义 但是 这样的排序算法排序算法有一个致命的弱点,当序列已经是有序序列时,其递归树成为单枝树,成为最坏的情况
优化快排
三者取中法
找到当前序列的最左,中间和最右位置,进行比较,避免最坏的情况。
template<class T>
T median3(T * arr, const int left, const int right)
{
// 取序列的前端,尾端,中间点,最小值放在left,中值放在right
int mid = (left + right)/2;
int k = left;
T temp;
if (arr[mid] < arr[k])
k = mid;
if (arr[right] < arr[k])
k = right;
if (k != left)
{
temp = arr[k];
arr[k] = arr[left];
arr[left] = temp;
}
if (mid != right && arr[mid] < arr[right])
{
temp = arr[mid];
arr[mid] = arr[right];
arr[right] = temp;
}
return arr[right];
}
快排再优化
在前辈们的研究之下发现,当序列元素小于25时,插入排序的效率会更高一些。
所以,我们使用快速排序和插入排序相结合的方式进行排序。
代码实现
```c++
#include<iostream>
using namespace std;
#define M 25
// 快速排序+插入排序混合排序算法
template<class T>
void HibridSort(T arr[], const int left, const int right)
{
// 先进行快速排序,然后对基本有序列进行插入排序
QuickSort(arr, left, right);
InsertSort(arr, left, right);
}
// 快速排序
template<class T>
void QuickSort(T arr[], const int left, const int right)
{
// 如果元素序列小于M时,插入排序效率更高
if (right - left <= M)
return;
// 进行排序
//划分
if (left < right){
int pivotpos = Partition(arr, left, right);
QuickSort(arr, left, pivotpos - 1);
QuickSort(arr, pivotpos + 1, right);
}
}
// 插入排序
template<class T>
void InsertSort(T * array,const int left,const int right)
{
int size = right - left;
int end = 0;//已经排好的最后一个数
int temp = 0;//需要排序的数
for (int i = 0; i < size - 1; i++)
{
end = i;
temp = array[end + 1];//将要排序的数标记
while (end >= 0 && array[end]>temp)
{
array[end + 1] = array[end];
end--;
}
array[end + 1] = temp;
}
}
template<class T>
T median3(T * arr, const int left, const int right)
{
// 取序列的前端,尾端,中间点,最小值放在left,中值放在right
int mid = (left + right)/2;
int k = left;
T temp;
if (arr[mid] < arr[k])
k = mid;
if (arr[right] < arr[k])
k = right;
if (k != left)
{
temp = arr[k];
arr[k] = arr[left];
arr[left] = temp;
}
if (mid != right && arr[mid] < arr[right])
{
temp = arr[mid];
arr[mid] = arr[right];
arr[right] = temp;
}
return arr[right];
}
template<class T>
int Partition(T arr[], const int left, const int right)
{
int i = left;
int j = right - 1;
T temp;
if (left < right)
{
T pivot = median3(arr, left, right);
for (;;)
{
while (i < j && arr[i] < pivot)
i++;
while (i < j && arr[j] > pivot)
j--;
if (i < j)
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
else
break;
}
if (arr[i] > pivot)
{
arr[right] = arr[i];
arr[i] = pivot;
}
}
return i;
}
int main()
{
int arr[25] = { 5, 6, 8, 3, 4, 99, 66, 55, 43, 45, 78, 32, 56, 98, 7, 23, 67, 17, 15, 44, 98, 0, 654, 2, 5464 };
//int arr[6] = { 6, 9, 3, 1, 2, 7 };
HibridSort<int>(arr, 0, sizeof(arr) / sizeof(arr[0]) - 1);
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
cout << arr[i] << " ";
return 0;
}
“`