高级排序算法(一):快速排序详解
引言
当我们处理大规模数据时,像冒泡排序、选择排序这样的基础排序算法就有点力不从心了。这时候,快速排序(Quick Sort)就派上用场了。
作为一种基于分治法的高效排序算法,快速排序在大多数情况下可以在O(n log n)的时间内完成排序。它不仅理论上效率高,而且在实际应用中表现也非常优异,是排序算法中的经典之作。
这篇文章将带你深入理解快速排序的原理、实现细节以及优化策略。
一、快速排序的核心思想
快速排序的核心是分治法(Divide and Conquer),它将问题分为更小的子问题逐一解决。快速排序的主要步骤如下:
- 选择一个基准值(Pivot):通常选取数组中的一个元素作为基准。
- 分区:
- 将小于基准值的元素放到左侧。
- 将大于基准值的元素放到右侧。
- 递归排序:
- 对左右两个部分分别递归地应用快速排序。
二、快速排序的分区方法
分区是快速排序的核心操作,它直接决定了算法的性能。常见的分区方法有两种:
1. Lomuto分区法
- 选取数组的最后一个元素作为基准值。
- 使用一个指针
i将数组分为两部分:- 左侧:小于基准值的元素。
- 右侧:大于基准值的元素。
- 最后将基准值放到正确的位置。
int lomutoPartition(int arr[], int low, int high) {int pivot = arr[high]; // 基准值int i = low - 1; // 指针 i 初始化在 low 的前面for (int j = low; j < high; j++) {if (arr[j] < pivot) { // 如果当前元素小于基准值i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp; // 交换 i 和 j 的元素}}// 将基准值放到正确的位置int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1; // 返回基准值的索引
}
2. Hoare分区法
- 使用两个指针:
- 左指针
i从左向右移动,找到第一个大于基准值的元素。 - 右指针
j从右向左移动,找到第一个小于基准值的元素。
- 左指针
- 交换
i和j的元素,直到两个指针相遇。 - 与Lomuto相比,Hoare分区法交换次数更少,适合大规模数据。
int hoarePartition(int arr[], int low, int high) {int pivot = arr[low]; // 基准值int i = low - 1;int j = high + 1;while (1) {do {i++;} while (arr[i] < pivot); // 从左向右找到大于等于 pivot 的元素do {j--;} while (arr[j] > pivot); // 从右向左找到小于等于 pivot 的元素if (i >= j) return j; // 指针相遇,返回分区点int temp = arr[i];arr[i] = arr[j];arr[j] = temp; // 交换 i 和 j 的元素}
}
三、快速排序的完整实现
以下是快速排序的完整实现,使用Lomuto分区法。
#include <stdio.h>// Lomuto 分区法
int partition(int arr[], int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;
}// 快速排序
void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high); // 分区点quickSort(arr, low, pi - 1); // 排序左部分quickSort(arr, pi + 1, high); // 排序右部分}
}int main() {int arr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);quickSort(arr, 0, n - 1);printf("排序后的数组: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}return 0;
}
四、快速排序的时间复杂度
快速排序的时间复杂度取决于分区点的选择:
- 最优情况:每次分区将数组均分为两部分,时间复杂度为 O(n log n)。
- 最坏情况:每次分区只分出一个元素,时间复杂度为 O(n²)。
- 平均情况:分区较为均衡,时间复杂度为 O(n log n)。
优化策略:
- 随机化基准值:随机选择基准值,避免最坏情况。
- 切换到插入排序:当子数组长度小于一定阈值时,使用插入排序提高效率。
五、快速排序与归并排序的对比
| 特性 | 快速排序 | 归并排序 |
|---|---|---|
| 时间复杂度 | 平均 O(n log n),最坏 O(n²) | 始终 O(n log n) |
| 空间复杂度 | 原地排序,O(log n) | O(n) |
| 稳定性 | 不稳定 | 稳定 |
| 适用场景 | 数据量大且内存有限 | 数据量大且对稳定性有要求 |
六、总结与展望
通过这篇文章,我们学习了快速排序的核心思想、分区方法以及完整实现。快速排序是基于分治法的高效算法,但它的性能依赖于分区点的选择,因此需要适当优化。
下一篇文章将聚焦于归并排序和堆排序,继续探索高级排序算法的魅力,敬请期待!
快速排序是排序算法中的明星选手,以其高效性和实用性广受欢迎。掌握快速排序,不仅能提升你对分治法的理解,还能为实际开发中优化程序性能打下基础。
如果你有疑问或需要进一步讲解的地方,欢迎在评论区讨论,我们一起进步!
相关文章:
高级排序算法(一):快速排序详解
引言 当我们处理大规模数据时,像冒泡排序、选择排序这样的基础排序算法就有点力不从心了。这时候,快速排序(Quick Sort)就派上用场了。 作为一种基于分治法的高效排序算法,快速排序在大多数情况下可以在O(n log n)的时…...
3.2 网络协议IP
欢迎大家订阅【计算机网络】学习专栏,开启你的计算机网络学习之旅! 文章目录 1 定义2 虚拟互连网络3 分组在互联网中的传送4 IPv4 地址 1 定义 网际协议 IP是 TCP/IP 体系中两个最主要的协议之一,也是最重要的互连网协议之一。IPv4 和 IPv6 …...
2024 一带一路暨金砖国家技能发展与技术创新大赛【网络安全防护治理实战技能赛项】样题(中职组)
2024 一带一路暨金砖国家技能发展与技术创新大赛【网络安全防护治理实战技能赛项】样题(中职组) 1.基础设置和安全强化(xxx 分)1.3. 任务内容: 2.安全监测和预警(xxx 分)2.1. 任务一:建立目录安…...
excel如何让单元格选中时显示提示信息?
现象: 当鼠标放在单元格上,会出现提示信息: 先选中单元格选择上方的【数据】-【数据验证】图标选择【输入信息】勾上【选定单元格时显示输入信息】输入【标题】,如:最上方图中的:姓名:输入【输…...
oscp备考,oscp系列——Kioptix Level 3靶场
Kioptix Level 3 oscp备考,oscp系列——Kioptix Level 3靶场 nmap扫描 主机发现 └─# nmap -sn 192.168.80.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-09 00:33 CST Nmap scan report for 192.168.80.1 Host is up (0.00014s latency). MAC…...
信创改造-达梦数据库配置项 dm.ini 优化
设置模式:兼容MySQL,COMPATIBLE_MODE 4 内存占比:90%,MAX_OS_MEMORY 90 目标内存:2G(不影响申请内存超过2G,但这部分内存不会回收),MEMORY_TARGET 2000 参考 https:…...
日本IT-需要掌握哪些技术框架?一篇通读
在日本从事IT工作,需要掌握的技术框架与全球范围内的趋势相似,但也有一些特定的技术和框架在日本更为流行。以下是一些在日本IT行业中常用的技术框架: Java后端 Java语言:Java在日本是一门非常稳定且受欢迎的编程语言࿰…...
错题:Linux C语言
题目:手写代码:判断一个数(int类型的整数)中有有多少1 题目:手写代码:判断一个数(转换成二进制表示时)有几个1 #include <stdio.h> int main(int argc, const char *argv[]) { //判断一个数…...
多表设计-一对多一对多-外键
一.多表设计概述: 二.一对多: 1.需求: 根据 页面原型 及 需求文档,完成部门及员工模块的表结构设计 -->部门和员工就是一对多,因为一个部门下会有多个员工,但一个员工只归属一个部门 2.页面原型&…...
Ch1:古今的manipulation与仿真、ROS和Drake介绍
不同的机器人研究与仿真 以前(15年左右)只能用仿真环境训练行走机器人,对于manipulation任务,有两个问题:1)相机不真实;2)接触行为太复杂。 I remember just a few years ago (~201…...
JAVA秋招面试题精选-第一天总结
目录 分栏简介: 问题一:订单表每天新增500W条数据,分库分表应该怎么设计? 问题难度以及频率: 问题导向: 满分答案: 举一反三: 问题总结: 问题二:解释…...
服务器卸载安装的 Node.js
卸载安装的 Node.js 版本,具体步骤取决于你是通过包管理器(如 yum 或 dnf)安装的,还是通过 nvm (Node Version Manager) 安装的。以下是针对这两种情况的指南。 通过包管理器卸载 Node.js 如果你是通过 yum 或 dnf 安装的 Node.…...
深度解析 Ansible:核心组件、配置、Playbook 全流程与 YAML 奥秘(下)
文章目录 六、playbook运行playbook方式Playbook VS ShellScripts忽略错误 ignore_errorshandlers和notify结合使用触发条件playbook中tags的使用playbook中变量的使用invertory参数模板templates迭代与条件判断迭代:with_items迭代嵌套子变量roles 六、playbook 运…...
使用go生成、识别二维码
1、下载 # 创建目录 # 进入目录 # 执行 go mod init xxx 命令(即:在当前目录初始化创建一个模块)# 下载gozxing go get github.com/makiuchi-d/gozxing 2、生成二维码 package mainimport ("image/png""os""gith…...
LLama系列模型简要概述
LLama-1(7B, 13B, 33B, 65B参数量;1.4T tokens训练数据量) 要做真正Open的AI Efficient:同等预算下,增大训练数据,比增大模型参数量,效果要更好 训练数据: 书、Wiki这种量少、质量高…...
2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判
2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判 完整代码请私聊 博主 一、背景 在各类学科竞赛中,常常要求参赛者提交 Excel 或/和 PDF 格式的竞赛作品。 本赛题以某届数据分析竞赛作品的评阅为背景,要求参赛者根据给定的评分准则和标准答案&a…...
MYSQL表联接算法深入研究
在关系型数据库中,表联接是一种常见的操作,它使得我们可以根据不同的条件将多个表中的数据进行连接。而MySQL作为一种常用的关系型数据库,其表联接算法包括NLJ、BNL、BKA、BNLH等多种,在实际应用中选择不同的算法还需要考虑到数据…...
markdown中画图功能mermaid
mermaid Mermaid 是一种开源的可交互式的数据可视化库,它使用 Markdown 标记语言来生成图表和流程图。它通常用于生成网站或文档中的图表。Mermaid 不属于任何公司,而是一个由社区开发和维护的开源项目。 官方网站: https://mermaid-js.git…...
SCI论文丨机器学习与深度学习论文
目录 第一章、ChatGPT-4o使用方法与技巧 第二章、ChatGPT-4o辅助文献检索、总结与分析 第三章、ChatGPT-4o辅助学术论文选题、创新点挖掘与实验方案设计 第四章、ChatGPT-4o辅助学术论文开题与大纲生成 第五章、ChatGPT-4o辅助学术论文写作马拉松活动介绍 第六章、ChatGPT…...
linux系统编程(二)
1、fcntl #include <unistd.h> int fcntl(int fd, int cmd, ...)fcntl用于控制文件描述符,该系统调用有很多功能,功能用cmd来控制,fcntl后面的参数根据cmd来填充。 我们常用的cmd有: F_GETFL:获取文件状态标志…...
智能缓存加速:重新定义扩散模型推理效率
智能缓存加速:重新定义扩散模型推理效率 【免费下载链接】ComfyUI-TeaCache 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-TeaCache 在AI创作领域,等待成为最大的创作阻力。当你使用扩散模型生成图像或视频时,是否曾因漫长的…...
群晖NAS人脸识别功能解锁指南:让旧设备焕发AI新活力
群晖NAS人脸识别功能解锁指南:让旧设备焕发AI新活力 【免费下载链接】Synology_Photos_Face_Patch Synology Photos Facial Recognition Patch 项目地址: https://gitcode.com/gh_mirrors/sy/Synology_Photos_Face_Patch 为何老款群晖NAS需要AI能力升级&…...
Java函数冷启动优化不是“选配”,而是SLA硬指标!一线大厂SRE团队正在紧急落地的6项Kubernetes调度增强策略
第一章:Java函数冷启动的本质与SLA倒逼机制Java函数冷启动并非单纯“首次加载慢”的表象,而是JVM生命周期、类加载机制、字节码验证、即时编译(JIT)预热及运行时元数据初始化等多层系统行为在无预热上下文下的集中爆发。当Serverl…...
MT5中文增强工具多场景落地:保险条款通俗化改写与消费者理解度提升实践
MT5中文增强工具多场景落地:保险条款通俗化改写与消费者理解度提升实践 1. 项目概述与核心价值 MT5中文增强工具是一个基于Streamlit和阿里达摩院mT5模型构建的本地化NLP工具,专门针对中文文本进行语义改写和数据增强。这个工具的最大特点是能够在保持…...
WAF工程师实战笔记:如何用Suricata规则精准识别哥斯拉、冰蝎、蚁剑的Webshell流量
WAF工程师实战笔记:Suricata规则精准识别主流Webshell流量 在安全运维的日常工作中,Webshell流量的检测始终是一场攻防对抗的持久战。面对哥斯拉、冰蝎、蚁剑等主流Webshell管理工具不断升级的流量混淆技术,传统的特征匹配方法往往力不从心。…...
Node.js全栈项目集成Wan2.1-UMT5:实时视频生成进度推送
Node.js全栈项目集成Wan2.1-UMT5:实时视频生成进度推送 最近在做一个挺有意思的项目,需要把Wan2.1-UMT5这个视频生成模型集成到我们自己的系统里。用户上传一段文字描述,系统就能生成一段短视频。听起来挺酷,对吧?但问…...
NBFC服务架构深度剖析:从硬件访问到用户界面的完整流程
NBFC服务架构深度剖析:从硬件访问到用户界面的完整流程 【免费下载链接】nbfc NoteBook FanControl 项目地址: https://gitcode.com/gh_mirrors/nb/nbfc NBFC(NoteBook FanControl)是一个跨平台的笔记本风扇控制服务,通过智…...
STM32F411 USB声卡时钟同步优化与中文命名实战
1. STM32F411 USB声卡开发基础 第一次接触STM32F411的USB声卡开发时,我被它的简洁配置流程惊艳到了。用CubeMX生成代码,接上PCM5102A解码芯片,不到半小时就能让电脑识别出音频设备。但很快我就发现事情没那么简单——播放音乐时总会出现周期…...
旧笔记本别扔!用飞牛OS+阿里云DDNS,5分钟搞定个人云盘外网访问
旧笔记本改造指南:用飞牛OS与阿里云DDNS打造高性价比个人云存储 你是否曾为家中堆积的旧电子设备感到困扰?那些性能落后但依然能正常运行的旧笔记本,其实蕴藏着巨大的实用价值。本文将带你探索如何将这些被时代淘汰的硬件变废为宝,…...
OpCore-Simplify高效配置实战指南:智能适配黑苹果硬件的开源工具
OpCore-Simplify高效配置实战指南:智能适配黑苹果硬件的开源工具 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 当你面对繁杂的黑苹果EFI…...
