快速排序是一种什么样的体验

最常用的排序算法,速度通常也是最快的。

时间复杂度:O(n*logn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
不稳定(比如 5 3 3 4 3 8 9 10 11 这个序列,在中枢元素5和3交换就会把元素3的稳定性打乱)

#include <iostream>
#include <algorithm>
#include <cmath>
#define MAX_LENGTH_INSERT_SORT 7
void m_swap(SqList *L,int low,int high);
int Partition(SqList *L,int low,int high);
void QSort(SqList *L ,int low , int high);
void QuickSort(SqList *L);

typedef struct SqList
{
    int r[10] = {1,8,12,3,14,5,13,15,23,45};
    int length = 9;
}SqList;

using namespace std;
int main()
{
    SqList L;
    for(int i = 0; i < 10; i++)
          cout << L.r[i] << " ";
    cout << endl;
    QuickSort(&L);
    for(int i = 0; i < 10; i++)
    cout << L.r[i] << " ";
}

m_swap交换二者的数值

void m_swap(SqList *L,int low,int high)
{
    int t = L->r[low];
    L->r[low] = L->r[high];
    L->r[high] = t;
}

Partition 选择中间值

int Partition(SqList *L,int low,int high)
{
    int pivotkey;
    pivotkey = L->r[low];
    while(low < high)
    {
        while(low < high && L->r[high] >= pivotkey)
            high--;
        m_swap(L,low,high);
        while(low < high && L->r[low] <= pivotkey)
            low++;
        m_swap(L,low,high);
    }
    return low;
}

优化选取中间轴: 取中间值越准确,节省时间越少。

int Partition(SqList *L,int low,int high)
{
    int pivotkey;
    int m = low + (high - low) / 2; //求出数组中间值
    if(L->r[low] > L->r[high])      //最小坐标跟最大坐标比较小的放在最右面
        swap(L,low,high);
    if(L->r[m] > L->r[high])        //中间坐标跟最大比较大的放在最左面
        swap(L,high,m);
    if(L->r[m] > L->r[low])         //将数值中间值放在low上。
        swap(L,m,low);
    pivotkey = L->r[low];
    while(low < high)
    {
        while(low < high && L->r[high] >= pivotkey)
            high--;
        m_swap(L,low,high);
        while(low < high && L->r[low] <= pivotkey)
            low++;
        m_swap(L,low,high);
    }
    return low;
}

递归分别对前后做出排序

void QSort(SqList *L ,int low , int high)
{
    int pivot;
    if(low < high)
    {
        pivot = Partition(L,low,high);
        QSort(L,low,pivot - 1);
        QSort(L,pivot + 1,high);
    }
}
void QuickSort(SqList *L)
{
    QSort(L,0,L->length);
}

优化不必要的交换

int Partition(SqList *L,int low,int high)
{
    int pivotkey;
    pivotkey = L->r[low];
    L->r[0] = pivotkey; //将取出的关键字备份
    while(low < high)
    {
        while(low < high && L->r[high] >= pivotkey)
            high--;
        L->r[low] = L->r[high];//采用替换的方式而不是交换的方式
        while(low < high && L->r[low] <= pivotkey)
            low++;
        L->r[high] = L->r[low];
    }
    L->r[low] = L->r[0];//替换完之后,将中间值放回去。
    return low;
}

快速排序对小数组排序的复杂度不如插入排序,所以我们可以加一个判断
如果是小数组的排序,直接使用插入排序等其他排序,小数组的定义范围
在 ( high - low ) 小于7到50之间的数由实际情况定。这样就能保证最大
的效率完成排序工作。

优化递归

void QSort1(SqList *L ,int low , int high)
{
    int pivot;
    if( (high - low) > MAX_LENGTH_INSERT_SORT)//判断是否需要快排
    {
        while(low < high)
        {
            pivot = Partition(L,low,high);
            QSort(L,low,pivot - 1);
            low = pivot + 1;
        }
    }
    else
        InsertSort(L); // 插入排序小数据排序应该考虑的排序
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值