快速排序介绍

快速排序(Quick Sort)是种高效的基于比较的排序算法,它采用了分治策略(Divide and Conquer)。其基本思想是通过选择一个基准值(pivot),将数组分为两部分,小于基准值的元素放在左边,大于基准值的元素放在右边,然后递归地对这两部分进行排序,最终使整个数组有序。

1. 算法步骤

  1. 选择基准值:从数组中选择一个元素作为基准值。通常可以选择数组的第一个元素、最后元素或中间元素等,这里以选择第一个元素为例。
  2. 分区操作
    • 定义两个指针,一个从数组的第二个元素开始(左指针),一个从数组的最后一个元素开始(右指针)。
    • 左指针向右移动,找到第一个大于基准值的元素;右指针向左移动,找到第一个小于基准值的元素。
    • 交换这两个元素的位置,然后继续移动指针,直到左指针超过右指针。
    • 此时,将基准值与右指针指向的元素交换位置,这样基准值就处于最终排序位置,将数组分为了两部分,左边部分都小于基准值,右边部分都大于基准值。
  3. 递归排序:对基准值左边和右边的子数组分别递归地应用快速排序算法,直到子数组的长度小于等于1(即已经有序)。

2. Python实现

以下是快速排序的Python实现代码:

def quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[0]left = []right = []for x in arr[1:]:if x <= pivot:left.append(x)else:right.append(x)return quick_sort(left) + [pivot] + quick_sort(right)

3. 时间复杂度分析

  1. 平均情况:快速排序的平均时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)。这是因为每次分区操作可以将数组大致分为两部分,递归地对这两部分进行排序,总共需要递归 log ⁡ n \log n logn 层,每层的操作时间复杂度为 O ( n ) O(n) O(n)(遍历数组进行分区)。
  2. 最坏情况:当数组已经有序或接近有序时,每次选择的基准值都是最大或最小元素,导致分区不均匀,时间复杂度会退化为 O ( n 2 ) O(n^2) O(n2)。例如,如果数组是升序排列,每次选择第一个元素作为基准值,那么左子数组将为空,右子数组包含除基准值外的所有元素,这样就需要进行 n − 1 n - 1 n1 次分区操作,总时间复杂度为 O ( n 2 ) O(n^2) O(n2)
  3. 最好情况:当每次选择的基准值都能将数组均匀地分为两部分时,时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),这是快速排序的最优情况。

4. 空间复杂度分析

  1. 平均情况:快速排序的空间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),这是由于递归调用栈的深度为 log ⁡ n \log n logn。在每次递归调用时,需要存储一些临时变量(如左右子数组),但这些变量在递归返回后会被释放,所以总体空间复杂度主要取决于递归调用栈的深度。
  2. 最坏情况:当递归深度达到 n n n 时(如数组已经有序或接近有序时),空间复杂度为 O ( n ) O(n) O(n)

5. 优化方法

  1. 随机选择基准值:为了避免最坏情况的发生,可以随机选择基准值,而不是固定选择第一个或最后一个元素。这样可以使基准值的选择更加随机,减少出现最坏情况的概率,提高算法的平均性能。
  2. 三数取中法:另一种改进方法是选择数组中的三个元素(如第一个、中间一个和最后一个),然后取中间值作为基准值。这种方法可以在一定程度上避免选择到极端值作为基准值,提高分区的平衡性。
  3. 尾递归优化:对于递归调用,可以进行尾递归优化,将递归调用转换为循环,减少递归调用栈的深度,从而降低空间复杂度。但在Python中,由于其对递归的实现方式,尾递归优化可能不会带来明显的性能提升,并且Python没有提供直接的尾递归优化机制。

6. 适用场景

快速排序适用于大多数需要排序的场景,特别是对大规模数据进行排序时,其平均时间复杂度较低,性能较好。但由于最坏情况下时间复杂度较高,在对基本有序的数组进行排序时,可能需要考虑其他更稳定的排序算法(如归并排序),或者对快速排序进行适当的优化(如随机选择基准值)以避免最坏情况的出现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/1522.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux自动分区后devmappercentos-home删除后合并到其它分区上

删除其他分区&#xff0c;合并到对应分区上增加磁盘空间 删除开机默认挂载 /dev/mapper/centos-home vim /etc/fstab 把 /dev/mapper/centos-home 这一行删除掉命令行取消挂载 /dev/mapper/centos-home umount /dev/mapper/centos-home删除掉逻辑卷 home lvsdf -hlvremove /…

东芝3525AC彩色复印机复印默认成黑白模式方法

同样适用2010AC等机型 东芝3525AC彩色激光数码复合机基本参数 产品类型&#xff1a;激光数码复合机 颜色类型&#xff1a;彩色 速度类型&#xff1a;中速 复印速度&#xff1a;彩色&#xff1a;35cpm&#xff0c;黑白&#xff1a;35cpm 涵盖功能&#xff1a;复印/打印/扫描…

T-SQL编程

目录 1、T-SQL的元素 1.1 标识符 1. 常规标识符 2. 分隔标识符 1.2 变量 1. 全局变量 2. 局部变量 1.3 运算符 1. 算数运算符 2. 赋值运算符 3. 位运算符 4. 比较运算符 5. 逻辑运算符 6. 字符串连接运算符 7. 一元运算符 8. 运算符的优先级和结合性 1.4 批处…

SpringBoot-Day1

1.Springboot入门 创建Maven工程 导入spring-boot-stater-web起步依赖 编写Controller 提供启动类 2.yml配置信息书写与获取 书写 # 发件人信息 email:user: 172349823457qq.comcode: sajdajlwhjfgfkllwhost: smtp.qq.comauth: true ​ # 学生爱好 hobbies:- 打篮球- 踢…

【Linux】从零开始:编写你的第一个Linux进度条小程序

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 文章目录 一、知识铺垫1.1 回车与换行概念1.2 缓冲区 二、实现简单倒计时三、进度条3.1 Verrs…

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发二

目录 1 -> 声明式UI开发指导 1.1 -> 开发说明 1.2 -> 创建页面 1.3 -> 修改组件样式 1.4 -> 更新页面内容 2 -> 创建简单视图 2.1 -> 构建Stack布局 2.2 -> 构建Flex布局 2.3 -> 构建食物数据模型 2.4 -> 构建食物列表List布局 2.5 -…

【React】新建React项目

目录 create-react-app基础运用React核心依赖React 核心思想&#xff1a;数据驱动React 采用 MVC体系package.jsonindex.html好书推荐 官方提供了快速构建React 项目的脚手架&#xff1a; create-react-app &#xff0c;目前使用它安装默认是19版本&#xff0c;我们这里降为18…

分多个AndroidManifest.xml来控制项目编译

使用场景 公司项目和我的项目的AndroidManifest.xml混在一起&#xff0c;我需要区分开来编译观察app运行 1.在app/src/main/ 下写多个AndroidManifest.xml AndroidManifest.own.xmlAndroidManifest.com.xml 2.编写powershell脚本 第一对脚本com-build.ps1和reset-com-mani…

linux进程

课本概念&#xff1a;程序的⼀个执行实例&#xff0c;正在执行的程序等内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的实体。 进程信息被放在一个叫做进程控制块的数据结构中&#xff0c;可以理解为进程属性的集合.课本上称之为PCB&…

Hadoop•安装JDK

听说这里是目录哦 创建目录❤️‍&#x1f525;上传JDK安装包&#x1f497;查看JDK是否上传成功&#x1f498;安装JDK&#x1f496;配置JDK系统环境变量&#x1f493;验证JDK是否安装成功&#x1f49e;分发JDK安装目录&#x1f48c;分发系统环境变量文件&#x1f49d;若显示没有…

[Deep Learning] Anaconda+CUDA+CuDNN+Pytorch(GPU)环境配置-2025

文章目录 [Deep Learning] AnacondaCUDACuDNNPytorch(GPU)环境配置-20250. 引子1. 安装Anaconda1.1 安装包下载&#xff1a;1.2 启用安装包安装1.3 配置(系统)环境变量1.4 验证Anaconda是否安装完毕1.5 Anaconda换源 2. 安装CUDACuDNN2.1 判断本机的CUDA版本2.2 下载适合自己CU…

网络原理(四)—— 网络层、数据链路层 与 DNS

网络层 网络层这里重点介绍 IP 协议&#xff0c;首先先解析 IP 数据包&#xff1a; 先介绍第一行&#xff1a; 4位版本号是指使用了哪一个版本的 IP 协议&#xff0c;这里有 IPV4 和 IPV6 两种协议&#xff0c;现在主要使用的是 IPV4 这一个版本号&#xff0c; IPV6 在国内也…

Redis快速入门店铺营业状态设置

Redis简介 Redis是一种基于内存的键值对&#xff08;K-V&#xff09;数据库。 这意味着它与MySQL数据库类似&#xff0c;都能够用于存储数据&#xff0c;但两者又有着本质的区别。首先两者存储数据的结构不一样&#xff0c;Redis通过键&#xff08;key&#xff09;和值…

Node.js 如何实现文件夹内文件批量重命名

文章目录 一、引言二、Node.js 简介2.1 是什么2.2 优势 三、Node.js 批量重命名原理3.1 涉及的核心模块3.2 关键函数 四、实战步骤4.1 环境搭建4.2 代码实现4.3 代码解释 五、案例分析5.1 场景描述5.2 解决方案 六、可能遇到的问题与解决方法6.1 常见错误6.2 解决方案 七、总结…

MySQL(高级特性篇) 04 章——逻辑架构

一、逻辑架构剖析 &#xff08;1&#xff09;服务器处理客户端请求 那服务器进程对客户端进程发送的请求做了什么处理&#xff0c;才能产生最后的处理结果呢&#xff1f;这里以查询请求为例展示&#xff1a;下面具体展开看一下&#xff1a;Connectors是MySQL服务器之外的客户…

滚动字幕视频怎么制作

在当今的视频创作领域&#xff0c;滚动字幕被广泛应用于各种场景&#xff0c;为视频增添丰富的信息展示和独特的视觉效果。无论是影视剧中的片尾字幕、新闻节目中的资讯滚动&#xff0c;还是综艺节目中的人员与鸣谢信息展示&#xff0c;滚动字幕都发挥着不可或缺的作用。接下来…

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(两种方法实现)

方法一&#xff1a;使用 systemd 服务文件 sudo yum install gcc make autoconf apr-devel apr-util-devel pcre-devel 1.下载源码 wget https://archive.apache.org/dist/httpd/httpd-2.4.46.tar.gz 2.解压源码 tar -xzf httpd-2.4.46.tar.gz 如果没有安装tar 记得先安装…

计算机视觉算法实战——步态识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 步态识别简介✨✨ 步态识别&#xff08;Gait Recognition&#xff09;是计算机视觉领域中的一个…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年&#xff0c;UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化&#xff0c;新的设计风向逐渐显现。了解并掌握这些趋势&#xff0c;对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

Leetcode - 周赛431

目录 一&#xff0c;3411. 最长乘积等价子数组 二&#xff0c;3412. 计算字符串的镜像分数 三&#xff0c;3413. 收集连续 K 个袋子可以获得的最多硬币数量 四&#xff0c;3414. 不重叠区间的最大得分 一&#xff0c;3411. 最长乘积等价子数组 本题数据范围小&#xff0c;直…