C++快速排序的实现(注释超详细)

本文详细介绍了C++中快速排序的实现方法,包括快速排序的基本思想、时间与空间复杂度分析,以及通过随机选取主元来提高算法稳定性的技巧。通过具体代码示例展示了如何进行分区操作,并提供了完整的快速排序实现。

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

C++快速排序的实现

1、QuickSort.h

/* 初始版本,升序排序 */
/* 时间复杂度:最好O(nlbn),平均O(nlbn),最坏0(n^2)
   空间复杂度:O(lbn) 递归栈最大深度为[lbn] + 1
   不稳定:情况基于每次划分选择的主元。随机化快排得到理论最坏情况的可能性仅为1/(2^n)
/*
* 快排思想:
* 1. 随机选取一个主元作为基准,从待排序记录序列左右两端开始,逐渐向中间靠拢,交替与主元比较、交换
* 左侧记录大于主元则交换,右侧记录大于主元则交换,交换后向中间靠拢
* 最后,主元到达它的最终位置
* 2. 对主元左右两个区域重复上述快速排序过程,结果分别让左右两个区域中的主元到达它们的最终位置
* 同时将待排序记录序列分成更小的待排序区域,再次对每个区域进行一趟快速排序,直到每个区域只有一个记录为止
*/

#ifndef QUICKSORT_H
#define QUICKSORT_H
#include <stdlib.h>

/* 从0开始,n为数组大小 */
int Partition(int arr[], int n)
{
    int pos = 0 + rand() % n;    // 随机选取主元 a + rand() % b = [a, b) 随机一个整数
    int main = arr[pos];       // 记录主元的值,后面将主元放置于最中间

    int low = 0, high = n - 1;
    std::swap(arr[0], arr[pos]);      /*  TODO :将主元跟最低位置的元素交换,这一步很重要 */
    while(low < high)   // 比较完毕之后,主元应该放置到的位置就是low == high,因为low == high时比较完毕,左边的比主元小,右边的比主元大,这就是主元所处的位置。
    {
        /* 必须从右边开始,因为要确保low == high时,arr[low]的值必须小于主元。即保证low == high右侧的元素大于等于主元。
        若从左边开始,则应先将主元与最高位置的元素交换      */
        while(low < high && arr[high] >= main)  // 找到右边区域比主元小的数
            --high;

        while(low < high && arr[low] <= main)   // 找到左边区域比主元大的数
            ++low;

        if(low < high)
            std::swap(arr[low], arr[high]); // 交换值
    }

    arr[0] = arr[low];  /* arr[0]保存的是主元的值,在循环中没有经过交换,而arr[low]的值小于主元,所以要把arr[low]放到主元左边 */
    arr[low] = main;	// 再把主元归位,记住此处 low == high
    return low;
}

void QuickSort(int arr[], int n)
{
    if(n <= 1)
        return;
    if(n > 1)
    {
        int p = Partition(arr, n);        // 选取一个主元,交换左右区域数据
        /* 去掉注释可以查看快排内部过程 */
        // std::cout << std::endl;
        // for(int i = 0; i < p; ++i)
        //     std::cout << arr[i] << " ";
        // std::cout << "**" << arr[p] << "** ";
        // for(int i = 0; i < n - p - 1; ++i)
        //     std::cout << arr[p + 1 + i] << " ";
        QuickSort(arr, p);                // 对左边区域进行快速排序
        QuickSort(arr + p + 1, n - p - 1);       // 对右边区域进行快速排序
    }
}


#endif // QUICKSORT_H

2、main.cpp

#include <iostream>
#include <stdlib.h>
#include "QuickSort.h"

#define MAX 10           // 随机数的最大数
#define MIN 1            // 随机数的最小数
#define MAXSIZE 10       // 数组大小
#define SORTTIMES 100    // 随机生成数组并进行排序的次数

int main(int argc, char *argv[])
{
    int arr[MAXSIZE];
    int i = SORTTIMES;
    while(i--){
        for(int i = 0; i < MAXSIZE; ++i)
        {
           arr[i] = (MIN + (int)MAX * rand() / (RAND_MAX + 1)); // 生成随机数组
           std::cout << arr[i] << " ";         // TODO : 输出生成的随机数,可注释掉
        }

        QuickSort(arr, MAXSIZE);            // 排序
        std::cout << "\t ==> \t";

        for(int i = 0; i < MAXSIZE; ++i)
            std::cout << arr[i] << " ";
        std::cout << std::endl;
    }
}

测试结果:

排序不得不看之:C++归并排序(注释超详细)

排序不得不看之:C++堆排序的实现(超详细)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值