【模板】快速排序

2023-11-20

题目链接:洛谷 P1177 【模板】快速排序

1960年由查尔斯·安东尼·理查德·霍尔(Charles Antony Richard Hoare,缩写为C. A. R. Hoare)提出。

如下图所示,快速排序的执行流程为:

① 从序列中选择一个轴点元素 pivot,假设每次选择最左边的元素为轴点元素。

② 利用 pivot 将序列分割成 2 个子序列:

  • 将小于 pivot 的元素放在 pivot 前面(左侧)
  • 将大于 pivot 的元素放在 pivot 后面(右侧)
  • 等于 pivot 的元素放哪边都可以

③ 对子序列进行 ①、② 操作,直到不能再分割(子序列中只剩下 1 个元素)。

在这里插入图片描述

从上图中可以发现,快速排序的每一轮处理其实就是将这一轮的轴点元素归位,直到所有的数都归位为止,排序就结束了。也就是说,快速排序的本质就是逐渐将每一个元素都转换成轴点元素。

如果轴点左右元素数量比较均匀,即最好情况下 T ( n ) = 2 ∗ T ( n / 2 ) + O ( n ) T(n) = 2 ∗ T(n/2) + O(n) T(n)=2T(n/2)+O(n),由 迭代和递归的时间复杂度分析 可知,时间复杂度为 O ( n log ⁡ n ) O(n \log{n}) O(nlogn)

如果轴点左右元素数量极度不均匀,即最坏情况下 T ( n ) = T ( n − 1 ) + O ( n ) T(n) = T(n-1) + O(n) T(n)=T(n1)+O(n),由 迭代和递归的时间复杂度分析 可知,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

平均时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)

由于递归调用的缘故,空间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

快速排序属于不稳定排序。

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100010;

int a[N];

void QuickSort(int left, int right)
{
    if (left >= right) return;
    
    int i = left, j = right;
    
    // 取中间的元素为轴点元素
    swap(a[left], a[left + right >> 1]);
    int pivot = a[left];
    
    while (i < j)
    {
        while (i < j && a[j] > pivot) j--;
        if (i < j) a[i++] = a[j];
        
        while (i < j && a[i] < pivot) i++;
        if (i < j) a[j--] = a[i];
    }
    
    // while循环退出时,i就是轴点位置,将轴点元素归位
    a[i] = pivot;
    
    QuickSort(left, i - 1); // 对轴点元素左边的元素[left,i-1]进行递归排序
    QuickSort(i + 1, right); // 对轴点元素右边的元素[i+1,right]进行递归排序
}

int main()
{
    int n;
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
    }
    
    QuickSort(0, n - 1);
    
    for (int i = 0; i < n; i++)
    {
        printf("%d%c", a[i], i == n - 1 ? '\n' : ' ');
    }
    
    return 0;
}

注意:

(1) 对于 洛谷 P1177 【模板】快速排序 来说,这道题的测试数据很严格,必须取中间的元素为轴点元素。

(2) 如果将下图中判断的位置分别改为 >=<=,代码提交会超时。因为这样会导致轴点元素分割出来的子序列极度不均匀,从而出现最坏时间复杂度 O ( n 2 ) O(n^2) O(n2)

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【模板】快速排序 的相关文章

随机推荐

  • 【ES6】Reflect反射机制

    文章目录 一 Reflect概述 二 用法详解 1 Object gt Reflect 2 修改Object方法的返回结果 3 命令式操作 gt 函数式操作 4 与Proxy对象的方法一一对象 5 apply 总结 一 Reflect概述
  • xshell如何连接远程服务器

    1 打开xshell后 点击新建 gt 会话 2 名称可以随意写 主机需要按照要求填写 远程服务器的IP在这里找 3 点击用户身份验证 4 按照要求填写用户名和密码 5 点击确定后 如果出现下面的命令则说明连接成功 6 再次打开xshell
  • 2021 CCF大数据与计算智能大赛个贷违约预测top 73 解决方案

    目录 一 概述 二 解题过程 2 1 数据 2 2 构建基线 2 3 进阶思路一 2 4 进阶思路二 2 5 进阶思路三 2 6 融合 2 7 调优提分过程 2 8 其他工作 三 结语 一 概述 这是我第二次参加大数据类型的竞赛 也是第一次
  • 如何在Word中粘贴出好看的代码

    文章目录 前言 使用highlightcode实现 总结 前言 每到毕业设计时 论文中一大段一大段的代码阅读起来很难受 这还是python代码 相对比较短 如果是STM32相关代码 看起来更难受 有没有一种办法让代码看起来舒服一些呢 使用h
  • java 数组的长度_Java如何获取数组和字符串的长度(length还是length())

    限时 1 秒钟给出答案 来来来 听我口令 Java 如何获取数组和字符串的长度 length 还是 length 在逛 programcreek 的时候 我发现了上面这个主题 说实话 我当时脑海中浮现出了这样一副惊心动魄的画面 面试官老马坐
  • python中添加空白和删除空白

    添加空白的方法 制表符 字符组合 t 换行符 字符组合 n 删除空白 方法名 功能 rstrip 剔除末尾的空白 lstrip 剔除开头的空白 strip 剔除两端的空白 在实际程序中 这些剥除函数最长用于在存储用户输入前对其进行清理
  • 时序预测

    时序预测 MATLAB实现TCN LSTM时间卷积长短期记忆神经网络时间序列预测 目录 时序预测 MATLAB实现TCN LSTM时间卷积长短期记忆神经网络时间序列预测 预测效果 基本介绍 模型描述 程序设计 参考资料 预测效果 基本介绍
  • win10下的anaconda安装pymysql

    1 打开anaconda的终端 即 anaconda prompt 2 输入命令 pip install pymysql ps 其余包都可以使用pip install xxx来完成安装 若下载失败 可在一下链接查找相关包进行安装 https
  • Java 单例模式、工厂模式、代理模式

    文章目录 单例模式 概念 单例模式的类型 破坏单例模式 枚举实现单例模式 工厂模式 概述 简单工厂模式 工厂方法 抽象工厂 代理模式 Proxy 概述 静态代理 动态代理 单例模式 概念 单例模式指在内存中创建对象且仅创建一次的设计模式 在
  • 《Pyramid Scene Parsing Network》

    Pytorch代码 1 研究问题 目前基于FCN的语义分割网络缺乏利用不同尺度全局上下文信息的能力 对于复杂图像的语义分割 如ADE20K数据集 存在问题 注 感受野的大小可以粗略表示为使用上下文信息的程度 2 研究方法 提出了金字塔场景理
  • Mybatis的常用注解

    加载配置文件的时候 绝对路径和相对路径的写法都不太好用 我们经常使用的两种方法第一种就是使用类加载器 他只能读取类路径的配置文件 第二种就是使用ServletContext对象的getRealPath 函数 mybatis的常用注解 1 与
  • jsp+servlet+ajax实现登录

    该案列使用jsp servlet ajax实现登录 页面简洁大方 弹框都是封装的插件 整体案列采用三层的模式 链接数据库方面用的是dbcp的链接池 数据库时mysql 运行效果如下图 下载地址 jsp servlet ajax实现登录案例
  • c++(对象赋值与拷贝构造函数)

    对象赋值 同一个类的对象之间可以相互赋值 默认情况下 进行的是对象成员之间的复制 也称为 按位复制 或 浅复制 当类的数据成员中没有指针类型的变量时 直接对两个对象进行赋值没有问题 但是一旦类的数据成员含有指针变量 那么直接对这两个对象进行
  • MySQL常用基础 - 小白必看(二)

    MySQL数据库基本操作 一 DDL 概念 是一个数据定义语言 该语言部分包括 1 对数据库的常用操作 创建数据库 1 create database 数据库名 直接删除 2 create database if not exists 数据
  • 《effective java》中关于解决构造函数/方法签名包含大量参数的解决方法

    针对构造方法 重叠构造器模式 重叠构造器模式是一种编程中的反模式 指的是一个类有多个构造函数 每个构造函数都有不同数量的参数 从而可以根据不同的情况创建对象 这种方式会导致代码可读性和可维护性降低 因为构造函数过多 参数顺序容易混淆 Jav
  • 使用 Composer 安装 JWT 失败错误 The "https://packagist.org/packages.json" file could not be downloaded 解决方案

    错误信息 The https packagist laravel china org packages json file could not be downloaded SSL operation failed with code 1 O
  • Redis3.0集群方案分析

    在Redis3 0集群出来之前 大家都对作者antirez寄予厚望 因为Redis从来没有让我们失望过 现在Redis3 0集群出来了 网上出了很多评论文章 都说他的功能多么强大 包括下面这张图是彻底把我欺骗了 等到我把Redis3 0客户
  • Qmake VS Cmake 对比讲解

    用 cmake 构建Qt工程 对比qmake进行学习 cmake vs qmake qmake 是为 Qt 量身打造的 使用起来非常方便 cmake 使用上不如qmake简单直接 但复杂换来的是强大的功能 内置的 out of source
  • 一点浩然气,千里快哉风

    到英国访学一年 也认识了一些其他来自国内的访问学者 平时周末也经常一起徒步聚餐 从今年1月份以来 基本每个月有一个小伙伴回国 随着身边的小伙伴越来越少 以及自己也要不久回国了 心里不免有些人走茶凉 曲终人散的落寞 总体上 来英国的访问学者很
  • 【模板】快速排序

    题目链接 洛谷 P1177 模板 快速排序 1960年由查尔斯 安东尼 理查德 霍尔 Charles Antony Richard Hoare 缩写为C A R Hoare 提出 如下图所示 快速排序的执行流程为 从序列中选择一个轴点元素