快速排序(分治,c++,白盒划分)

想要理解快速排序,首先要理解”一趟快速排序“,就是找一个记录,以它的关键字作为“枢轴”,凡其关键字小于枢轴的记录均移动至该记录之前,反之,凡关键字大于枢轴的记录均移动至该记录之后。
这样致使一趟排序之后,记录的无序序列R[s…t]将分割成两部分:R[s…i-1]和R[i+1…t],且
R[j].key(s≤j≤i-1)≤ R[i].key(枢轴 ) ≤ R[j].key(i+1≤j≤t)
一次快速排序代码下:
代码选用排序数组片段的第一个元素作为”枢轴“。

int sort(vector<int>& num, int low, int high)
{
    int key = num[low];//将num[low]保存起来
    while (low < high)
    {
        while (low < high && num[high] > key)
        {
            high--;
        }
        num[low] = num[high];
        while (low < high && num[low] < key)
        {
            low++;
        }
        num[high] = num[low];
    }
    num[low] = key;
    return low;//此时low必定等于high,返回谁都是枢轴
}

接下来就是利用分治的思想划分数组,递归求解。
代码如下:

void Qsort(vector<int>& num, int low, int high)
{
    if (low < high)//只要有两个以上元素,调用一趟快速排序
    {
        int key = sort(num, low, high);
        Qsort(num, low, key - 1);//调用一趟快速排序,不是递归
        Qsort(num, key + 1, high);
    }
}

完整代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int sort(vector<int>& num, int low, int high)
{
    int key = num[low];//将num[low]保存起来
    while (low < high)
    {
        while (low < high && num[high] > key)
        {
            high--;
        }
        num[low] = num[high];
        while (low < high && num[low] < key)
        {
            low++;
        }
        num[high] = num[low];
    }
    num[low] = key;
    return low;//此时low必定等于high,返回谁都是枢轴
}

void Qsort(vector<int>& num, int low, int high)
{
    if (low < high)//只要有两个以上元素,调用一趟快速排序
    {
        int key = sort(num, low, high);
        Qsort(num, low, key - 1);//调用一趟快速排序,不是递归
        Qsort(num, key + 1, high);
    }
}


int main() {
    int b[10] = { 52, 49, 80, 36, 14,  58, 61, 97, 23, 75 };//测试用例
    vector<int> a(b, b + 10);
    Qsort(a, 0, 9);
    for (auto i : a)
    {
        cout << i << endl;
    }
    return 0;
}

快速排序的时间复杂度分析:
最好的情况:
每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlogn)
最坏的情况:
每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)
由于枢轴的选取具有随机性,因此快排平均时间复杂度为O(nlogn)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值