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

快速排序

简单快排

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

“`

猜你喜欢

转载自blog.csdn.net/qq_37934101/article/details/81194514