【十大排序算法】快速排序
在乱序的世界中,快速排序如同一位智慧的园丁,
以轻盈的手法,将无序的花朵们重新安排,
在每一次比较中,沐浴着理性的阳光,
终使它们在有序的花园里,开出绚烂的芬芳。
文章目录
- 一、快速排序
- 二、发展历史
- 三、处理流程
- 四、算法实现
- 五、快速排序的特性
- 六、小结
- 推荐阅读
一、快速排序
快速排序是一种高效的排序算法,它采用了分治的策略。它的基本思想是选择一个基准值,将数组分为两个子数组,一个子数组中的所有元素都小于基准值,另一个子数组中的所有元素都大于基准值,然后对这两个子数组递归地进行排序。
具体来说,快速排序的步骤如下:
- 选择一个基准值(通常是数组的第一个元素、最后一个元素或者中间元素)。
- 将数组分为两个子数组,一个子数组中的所有元素都小于基准值,另一个子数组中的所有元素都大于基准值。
- 对这两个子数组递归地进行排序。
- 将排好序的子数组合并起来,即得到有序数组。
快速排序的关键在于分割操作,通过这个操作,它可以将一个大问题分解成两个规模较小的子问题,然后分别解决,最终达到整体有序的目的。
二、发展历史
快速排序是由英国计算机科学家 Tony Hoare
在 1960 1960 1960 年代提出的。Hoare 最初将这一算法称为 “分区交换排序”,后来更广泛地称为快速排序。他的灵感来自于合并排序和插入排序。
- 早期思想: Hoare 注意到合并排序在实践中性能良好,但需要额外内存空间;而插入排序则内存消耗较少,但在大规模数据下性能不佳。他希望能够结合两者的优点,创造出一种既能够节省空间又能够在平均情况下具有良好性能的排序算法。
- Hoare 分区法: Hoare 提出了一种称为 Hoare 分区法的分区策略,这成为了快速排序的核心部分。这个方法从数组中选择一个基准值,将数组分成两个部分,左边的部分包含比基准值小的元素,右边的部分包含比基准值大的元素。然后,递归地对这两个部分进行排序。
- 论文发表: Hoare 在 1961 1961 1961 年发表了关于快速排序的论文,论文中描述了这一算法的基本原理和实现方法。此后,他不断改进和优化这一算法,使得快速排序成为了一种非常高效的排序算法。
- 持续优化: 随着计算机科学的发展,许多学者对快速排序进行了进一步的优化和改进。例如,采用随机化的方式选择基准值,以防止最坏情况的发生;使用三数取中法来选择基准值,以提高算法的稳定性和性能等。
- 现代应用: 至今,快速排序仍然是一种非常流行和高效的排序算法,被广泛应用于各种编程语言和实际应用中。其简洁而优雅的设计理念以及优秀的性能使得它成为了排序算法中的经典之作。
三、处理流程
场景假设:我们需要将下列无序序列使用快速排序按从小到大进行排序。
快速排序的流程如下:
- 在原序列中选取第一个元素 3 3 3 作为 Pivot 哨兵
- 将序列中小于 Pivot 的元素,放在 Pivot 的左边,大于 Pivot 的元素放在 Pivot 的右边
- 递归处理 Pivot 左边的序列和右边的序列
- 当子序列为长度 1 1 1 时终止
四、算法实现
// 快速排序入口
void quickSort(int[] arr, int low, int high) {if (low < high) {// 对数组进行分区操作int pivot = partition(arr, low, high);// 递归排序左半部分quickSort(arr, low, pivot - 1);// 递归排序右半部分quickSort(arr, pivot + 1, high);}
}// 分区操作
int partition(int[] arr, int low, int high) {// 选择最后一个元素作为 pivotint pivot = arr[high];int i = low - 1; // 指向小于 pivot 的区域的边界// 遍历数组,将小于 pivot 的元素放到左侧for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;// 交换元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将 pivot 放到正确位置int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;// 返回 pivot的位置return i + 1;
}public static void main(String[] args) {int[] arr = {5, 3, 8, 6, 2, 7, 1, 4};// 调用快速排序算法quickSort(arr, 0, arr.length - 1);// 输出排序后的数组System.out.print("Sorted array: ");for (int num : arr) {System.out.print(num + " ");}
}
算法时间复杂度分析:
情况 | 时间复杂度 | 计算公式 | 公式解释 |
---|---|---|---|
最好情况 | O ( n l o g n ) O(nlogn) O(nlogn) | T ( n ) = 2 T ( n 2 ) + n T(n) = 2T(\frac{n}{2}) + n T(n)=2T(2n)+n | 在最优情况下,每次划分都能将数组均匀地分成两部分。因此,我们有两个大小为 n 2 \frac{n}{2} 2n 的子问题,所以有 2 T ( n 2 ) 2T(\frac{n}{2}) 2T(2n)。然后,我们需要 n n n 的时间来进行划分操作。所以,总的时间复杂度就是 2 T ( n 2 ) + n 2T(\frac{n}{2}) + n 2T(2n)+n |
平均情况 | O ( n l o g n ) O(nlogn) O(nlogn) | T ( n ) = T ( n 2 ) + T ( n 2 ) + n T(n) = T(\frac{n}{2}) + T(\frac{n}{2}) + n T(n)=T(2n)+T(2n)+n | 在平均情况下,我们假设每次划分都能将数组均匀地分成两部分。因此,我们有两个大小为 n 2 \frac{n}{2} 2n 的子问题,所以有 T ( n 2 ) + T ( n 2 ) T(\frac{n}{2}) + T(\frac{n}{2}) T(2n)+T(2n)。然后,我们需要 n n n 的时间来进行划分操作。所以,总的时间复杂度就是 T ( n 2 ) + T ( n 2 ) + n T(\frac{n}{2}) + T(\frac{n}{2}) + n T(2n)+T(2n)+n |
最坏情况 | O ( n 2 ) O(n^2) O(n2) | T ( n ) = T ( n − 1 ) + n T(n) = T(n - 1) + n T(n)=T(n−1)+n | 在最坏情况下,每次划分只能将数组划分为一份有 n − 1 n - 1 n−1 个元素,另一份有 0 0 0 个元素。因此,我们有一个大小为 n − 1 n - 1 n−1 子问题,所以有 T ( n − 1 ) T(n - 1) T(n−1)。然后,我们需要 n n n 的时间来进行划分操作。所以,总的时间复杂度就是 T ( n − 1 ) + n T(n - 1) + n T(n−1)+n |
五、快速排序的特性
快速排序具有以下特性:
- 稳定性: 在一般情况下,快速排序是
不稳定的
,即相同元素在排序后可能会改变相对位置。 - 原地性: 快速排序是一种原地排序算法,不需要额外的辅助空间,只需要使用原始数组进行排序。
- 适应性: 快速排序适用于各种数据类型,并且对部分有序的数据排序效果良好。
- 高效性: 快速排序在平均情况下具有 O ( n l o g n ) O(nlogn) O(nlogn) 的时间复杂度,使其成为处理大规模数据的理想选择。
六、小结
快速排序是一种非常重要且高效的排序算法,适用于各种数据类型和应用场景。其原地性、高效性以及简单直观的实现使得它成为了排序算法中的经典之作。
推荐阅读
- Spring 三级缓存
- 深入了解 MyBatis 插件:定制化你的持久层框架
- Zookeeper 注册中心:单机部署
- 【JavaScript】探索 JavaScript 中的解构赋值
- 深入理解 JavaScript 中的 Promise、async 和 await
相关文章:
【十大排序算法】快速排序
在乱序的世界中,快速排序如同一位智慧的园丁, 以轻盈的手法,将无序的花朵们重新安排, 在每一次比较中,沐浴着理性的阳光, 终使它们在有序的花园里,开出绚烂的芬芳。 文章目录 一、快速排序二、…...
linux系统ubuntu中在命令行中打开图形界面的文件夹
在命令行中打开当前路径,以文件管理器的形式打开: 命令 # 打开文件管理器 当前的路径 nautilus .nautilus 是一个与 GNOME 桌面环境集成的文件管理器的命令行启动程序。在 Linux 系统中,特别是使用 GNOME 作为桌面环境时,用户经…...
【C++11数据结构与算法】C++ 栈
C 栈(stack) 文章目录 C 栈(stack)栈的基本介绍栈的算法运用单调栈实战题LC例题:[321. 拼接最大数](https://leetcode.cn/problems/create-maximum-number/)LC例题:[316. 去除重复字母](https://leetcode.cn/problems/remove-duplicate-letters/) 栈的基…...
pdf文件如何防篡改内容
PDF文件防篡改内容的方法有多种,以下是一些常见且有效的方法,它们可以帮助确保PDF文件的完整性和真实性: 加密PDF文档: 原理:通过设置密码来保护PDF文档,防止未经授权的访问和修改。注意事项:密…...
QT 音乐播放器【二】 歌词同步+滚动+特效
文章目录 效果图概述代码解析歌词歌词同步歌词特效 总结 效果图 概述 先整体说明一下这个效果的实现,你所看到的歌词都是QGraphicsObject,在QGraphicsView上绘制(paint)出来的。也就是说每一句歌词都是一个图元(item)。 为什么用QGraphicsView框架&…...
关于怎么用Cubemx生成的USBHID设备实现读取一体的鼠标键盘设备(改进版)
主要最近做了一个要用STM32实现读取鼠标键盘一体的那种USB设备,STM32的界面上要和电脑一样的能通过这个USB接口实现鼠标移动,键盘的按键。然后我就很自然的去参考了正点原子的例程,可是找了一圈,发现正点原子好像用的库函数&#…...
Soildworks学习笔记(二)
放样凸台基体: 自动生成连接两个物体两个面的基体: 2.旋转切除: 3.剪切实体: 4.转换实体引用: 将实体的轮廓线转换至当前草图使其成为当前草图的图元,主要用于在同一平面或另一个坐标中制作草图实体或其尺寸的副本。 …...
Linux配置uwsgi环境
Linux配置uwsgi环境 1.进入虚拟环境 source /envs/django_-shop-system/bin/activate2.安装uwsgi pip install uwsgi3.基于uwsgi运行项目 – 基于配置文件 在项目目录下创建配置文件 #socket 0.0.0.0:8005 http 0.0.0.0:8005 # http120.55.47.111:8005 chdir/opt/www/djang…...
Nagios的安装和使用
*实验* *nagios安装和使用* Nagios 是一个监视系统运行状态和网络信息的监视系统。Nagios 能监视所指定的本地或远程主机以及服务,同时提供异常通知功能等. Nagios 可运行在 Linux/Unix 平台之上,同时提供一个可选的基于浏览器的 WEB 界面以方便系统管…...
Numba 的 CUDA 示例(4/4):原子和互斥
本教程为 Numba CUDA 示例 第 4 部分。 本系列第 4 部分总结了使用 Python 从头开始学习 CUDA 编程的旅程 介绍 在本系列的前三部分(第 1 部分,第 2 部分,第 3 部分)中,我们介绍了 CUDA 开发的大部分基础知识…...
【机器学习】机器学习引领AI:重塑人类社会的新纪元
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀机器学习引领AI 📒1. 引言📕2. 人工智能(AI)🌈人工智能的发展🌞应用领…...
【制作面包game】
编写一个制作面包的游戏代码涉及到游戏设计、编程和用户界面设计等多个方面。这里我可以提供一个简化版本的Python代码示例,用于创建一个基本的面包制作游戏。这个游戏将会有一个简单的用户界面,玩家可以通过输入命令来制作面包。 游戏的基本流程如下&a…...
Django更改超级用户密码
Django更改超级用户密码 1、打开shell 在工程文件目录下敲入: python manage.py shell再在python交互界面输入: from django.contrib.auth.models import User user User.objects.get(username root) user.set_password(123456) user.save()其中ro…...
ROS基础学习-ROS通信机制进阶
ROS通信机制进阶 目录 0.简介1.常用API1.1 节点初始化函数1.1.1 C++1.1.2 Python1.2 话题与服务相关函数1.2.1 对象获取相关1.2.1.1 C++1.2.1.2 Python1.2.2 订阅对象相关1.2.2.1 C++1.2.2.2 Python1.2.3 服务对象相关函数1.2.3.1 C++1.2.3.2 Python1.2.4 客户端对象相关1.2.4.…...
【Vue3】shallowReactive() and shallowReadonly()
历史小剧场 所谓历史,就是过去的事,它的残酷之处在于:无论你哀嚎,悲伤,痛苦,落寞,追悔,它都无法改变。 一具有名的尸体躺在无数无名的尸体上,这就是所谓的霸业。---- 《明…...
【javaEE初阶】
🌈🌈🌈关于java ⚡⚡⚡java的由来 我们这篇文章主要是来介绍javaEE,一般称为java企业版,实际上java的历史可以追溯到上个世纪90年代,当时主要的语言主流的还是C语言和C,但是在那个时期嵌入式初…...
深度学习 - 梯度下降优化方法
梯度下降的基本概念 梯度下降(Gradient Descent)是一种用于优化机器学习模型参数的算法,其目的是最小化损失函数,从而提高模型的预测精度。梯度下降的核心思想是通过迭代地调整参数,沿着损失函数下降的方向前进&#…...
Steam下载游戏很慢?一个设置解决!
博主今天重装系统后,用steam下载发现巨慢 500MB,都要下载半小时。 平时下载软件,一般1分钟就搞定了,于是大致就知道,设置应该出问题了 于是修改了,如下设置之后,速度翻了10倍。 如下&#x…...
51单片机采用定时器T1的方式1的中断计数方式,外接开关K4按4次后,8只LED闪烁不停
1、功能描述 采用定时器T1的方式1的中断计数方式,外接开关K4按4次后,8只LED闪烁不停 2、实验原理 定时器原理:8051的定时器可以用于计数外部事件或执行内部定时操作。在本程序中,定时器1被设置为模式2,即8位自动重装载定时器模式…...
windows系统 flutter 开发环境配置
1、管理员运行powershell,安装:Chocolatey 工具,粘贴复制运行下列脚本: Chocolatey 官方安装文档 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePointManage…...
【线性代数】SVDPCA
用最直观的方式告诉你:什么是主成分分析PCA_哔哩哔哩_bilibili 奇异值分解singular value decomposition,SVD principal component analysis,PCA 降维操作 pca就是降维后使得信息损失最小 投影在坐标轴上的点越分散,信息保留越多 pca的实现…...
1.Vue2使用ElementUI-初识及环境搭建
目录 1.下载nodejs v16.x 2.设置淘宝镜像源 3.安装脚手架 4.创建一个项目 5.项目修改 代码地址:source-code: 源码笔记 1.下载nodejs v16.x 下载地址:Node.js — Download Node.js 2.设置淘宝镜像源 npm config set registry https://registry.…...
OS复习笔记ch7-3
承接上文我们讲完了页式管理和段式管理,接下来让我们深入讲解一下快表和二级页表 快表 快表和计算机组成原理讲的Cache原理如出一辙。为了减少访存的次数,OS在访问页面的时候创建了快表(Translation Lookaside Buffer ,简称TLB&…...
MFC 教程-回车时窗口退出问题
【问题描述】 MFC窗口默认时,按回车窗口会退出 【原因分析】 默认调用OnOK() 【解决办法】 重写虚函PreTranslateMessage BOOL CTESTMFCDlg::PreTranslateMessage(MSG* pMsg) {// TODO: 在此添加专用代码和/或调用基类// 修改回车键的操作反应 if (pMsg->…...
CTFHUB-SQL注入-字符型注入
目录 查询数据库名 查询数据库中的表名 查询表中数据 总结 此题目和上一题相似,一个是整数型注入,一个是字符型注入。字符型注入就是注入字符串参数,判断回显是否存在注入漏洞。因为上一题使用手工注入查看题目 flag ,这里就不…...
Docker配置Redis集群以及主从扩容与缩容
基础镜像拉取 docker run -p 6379:6379 -d redis:6.0.8 配置文件以及数据卷挂载 # 开启密码验证(可选) requirepass 1234 # 允许redis外地连接,需要注释掉绑定的IP # bind 127.0.0.1 # 关闭保护模式(可选) protected-m…...
【计算机网络】 传输层
一、传输层提供的服务 1.1 传输层的功能 1.1.1 传输层的功能如下: 传输层提供应用进程之间的逻辑通信(即端到端的通信)。与网络层的区别是:网络层提供的是主机之间的逻辑通信。 1.1.2 复用和分用 传输层要还要对收到的报文进行…...
山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十七)- 微服务(7)
11.1 : 同步调用的问题 11.2 异步通讯的优缺点 11.3 MQ MQ就是事件驱动架构中的Broker 安装MQ docker run \-e RABBITMQ_DEFAULT_USERxxxx \-e RABBITMQ_DEFAULT_PASSxxxxx \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management 浏览器访问1…...
Java Web应用,IPv6问题解决
在Java Web程序中,如果使用Tomcat并遇到了IPv6相关的问题,可以通过以下几种方式来解决: 1. 配置Tomcat以使用IPv4 默认情况下,Java可能会优先使用IPv6。如果你希望Tomcat使用IPv4,最简单的方法是通过设置系统属性来强…...
MyBatis二级缓存开启条件
MyBatis缓存为俩层体系。分为一级缓存和二级缓存。 一级缓存: 一级缓存默认开启,一级缓存的作用域是SqlSession级别的,这意味着当你更换SqlSession之后就不能再利用原来的SqlSession的一级缓存了。不同的SqlSession之间的一级缓存是隔离的。…...
网站关键词推广哪家好/搜索引擎营销的主要方式有
2019独角兽企业重金招聘Python工程师标准>>> 一.系统目录结构 1.linux系统目录图 2.目录介绍 /bin:bin是Binary的缩写,该目录下存放的是最常用的命令。/boot:该目录下存放的是启动Linux时使用的一些核心文件,包括一些连…...
越南的网站建设/百度推广优化怎么做的
首先请大家看这么一个简单的小程序: #include <stdio.h>void main(){int i, b[10];for ( i 0; i < 10; i ) { b[i] 0; }} 请问这个程序是否有错?A.正常 B.越界 C.死循环 正确答案是C,相信选A或选B的朋友一定会很纳闷…...
直播app开发需求/西安百度推广优化公司
平时真不怎么关注printf的返回值,一般是直接调用printf格式化输出,今天做腾讯的笔试题发现了一个知识漏洞,特此记录。 首先,题目是这样的:int f(int a, int b, int c){ return 0;}int main(){ return f(printf("a…...
wordpress对空间的要求/小广告网页
刚来到公司,组里前辈就建议用 Foxmail 收发邮件,今天刚刚在 Foxmail 上设置如何自动添加落款签名。 由于跟百度搜索到的方法不太一样,可能根据电脑版本不同 Foxmail 设置方法不同,所以记录在博客中,供大家参考~ 公司…...
门户网站模板 免费/专业seo网站优化推广排名教程
好程序员web前端教程分享JavaScript验证API,小编每天会分享一下干货给大家。那么今天说道的就是web前端培训课程中的章节。JavaScript验证API约束验证DOM方法PropertyDescriptioncheckValidity()如果 input 元素中的数据是合法的返回 true,否则返回 fals…...
设计专业招聘网站/seo推广是什么意思
在今天的这篇文章中,我们将介绍如何读取一个CSV文件,并使用一个table进行展示数据。我们知道在Ubuntu平台中目前没有移植TableView。那么我们怎么来展示一个Table的数据呢? 首先,在Ubuntu桌面上,我们可以使用我们的Lib…...