[排序算法]C++实现快速排序

本文详细介绍了快速排序算法的基本思想和实现步骤,包括一趟快速排序的过程、递归排序子序列的方法及C++实现代码。同时,文章还分析了快速排序的时间复杂度、空间复杂度及其最优、最坏情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本思想

  快速排序(Quick Sort)是对冒泡排序的一种改进。
  它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
  假设待排序列为{x0,x2,,xn1}{x0,x2,…,xn−1},首先任意选取一个记录(通常可选第一个记录)作为枢轴(pivot),然后将关键字比pivot小的都安置在它的位置之前,比pivot大的都放在它的位置之后。由此该枢轴最后所落的位置i作分界线将序列分成两个子序列{x0,x1,,xi1}{x0,x1,…,xi−1}{xi+1,xi+2,xn1}{xi+1,xi+2…,xn−1}。这个过程称为一趟快速排序(或一次划分)。


实现快速排序的步骤

  1. 将待排序列进行一趟快速排序,将序列一分为二。
  2. 对较小子序列递归排序
  3. 对较大子序列递归排序

一趟快速排序——交换步骤
附设两个指针iStart和iEnd,初值分别为待排序列的头和尾,枢轴的关键字为iPivotKey
1. 将枢轴记录保存起来
2. 从iEnd位置起向前搜索找到第一个关键字小于 iPivotkey的记录,对iStart指针所指位置的值覆盖
3. 从iStart位置起向后搜索找到第一个关键字大于 iPivotkey的记录,对iEnd指针所指位置的值覆盖
4. 只要符合iStart < iEnd,循环2和3步骤
5. 循环结束后,将第一步保存的枢轴记录归位,并返回枢轴位置


C++实现

/*
    交换iArr中子序列[iStart, iEnd]的记录,枢轴记录归位,并返回其所在位置
    此时在它之前的记录均不大于它,在它之后的记录均不小于它
*/
int Partition(int iArr[], int iStart, int iEnd)
{
    // 先将枢轴记录保存
    int iPivotKey = iArr[iStart];
    while (iStart < iEnd)
    {
        // 从iEnd位置起向前搜索找到第一个关键字小于iPivotkey的记录
        while (iStart < iEnd && iArr[iEnd]  > iPivotKey)
        {
            iEnd--;
        }
        iArr[iStart] = iArr[iEnd];

        // 从iStart位置起向后搜索找到第一个关键字大于iPivotkey的记录
        while (iStart < iEnd && iArr[iStart] < iPivotKey)
        {
            iStart++;
        }
        iArr[iEnd] = iArr[iStart];
    }

    iArr[iStart] = iPivotKey;  // 枢轴记录归位
    return iStart;             // 返回枢轴位置
}

void QuickSort(int iArr[], int iStart, int iEnd)
{
    if (iStart < iEnd)
    {
        int iPivot = Partition(iArr, iStart, iEnd); // 将序列一分为二
        QuickSort(iArr, iStart, iPivot - 1);        // 对低子序列递归排序
        QuickSort(iArr, iPivot + 1, iEnd);          // 对高子序列递归排序
    }
}

总结

时间复杂度
  通常,快速排序被认为是,在所有同数量级O(nlogn)O(nlogn)的排序方法中,其平均性能最好。但是,若初始记录按关键字有序或基本有序时,快速排序将蜕化为冒泡排序,其时间复杂度为O(n2)O(n2)

空间复杂度
  快速排序需要一个栈空间来实现递归。
  若每一趟排序都将记录序列均匀地分割成长度相接近的两个子序列,则栈的最大深度为log2n+1⌊log2n⌋+1
  若每趟排序之后,枢轴位置均偏向子序列的一端,则为最坏情况,栈的最大深度为n。

最坏时间复杂度最优时间复杂度平均时间复杂度空间复杂度
O(n2)O(n2)O(nlogn)O(nlogn)O(nlogn)O(nlogn)O(n)O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值