快速排序
簡單快排
快速排序(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;
}
“`