七大排序算法--快速排序及優化

快速排序

簡單快排

快速排序(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;
}

“`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章