快速排序算法详解

算法原理

快速排序是一种分治的策略的排序算法。它的核心排序思想是将问题不断的分解为子问题。以数组为例进行介绍更容易理解,创建一个数组或者vector,假设是std::vector<int> a{3,2, 1, 5, 4,7},要对a从小到大进行排序:

  1. 首先在a中任意选择一个数值(为了简单起见,这个中间值每次都取数组的第一个数值即可),以这个数值为中间值,通过遍历的方式分别找出小于这个中间值的所有数字放到一个数组或者vector中,这里将包含所有小于中间值数字的数组成为left;同时找出所有大于这个中间值的数字放到一个数组或者vector中,这里将包含所有大于中间值数字的数组成为right。
  2. 将数组left作为一个新的整体,重复1的操作,直到数组的长度小于等于1截止,停止重复。
  3. 第2步完成后,整个left子数组已经是一个有序的数组
  4. 将数组right作为一个新的整体,重复1的操作,直到数组的长度小于等于1截止,停止重复。
  5. 第4步完成后,整个right子数组已经一个有序的数组
  6. 拼接数组,left数组+中间值+right数组

上面的过程有一个隐性的排序,即在步骤1中每次都会都数组根据中间值编译找出所有小于这个中间值的数字和大于中间值的数组,然后再对子数组重复进行同样的操作,直到最后的子数组长度为1的时候,就完成了这个排序,可以这样理解,在每次问题分解过程中都会遍历当前数组根据选择的数值作为临界值进行一次“排序”,这里的“排序”并不是对整个数组进行排序,而是以选择的临界值分别找出小于这个临界值和大于这个临界值的数字,虽然小于或大于这个临界值的部分没有进行排序,但是我们我们可以将他们继续分解,继续在他们中找出一个临界值,重复这个过程,直至数组的大小为1。这样整个数组通过这样的方式实现了排序的需求。

把上面的内容进行归纳总结:

快速排序是一种分治策略(Divide and Conquer)的排序算法:

  • 选择一个基准值(pivot)
  • 将数组分为两部分:小于基准值的部分和大于基准值的部分
  • 递归地对这两部分进行排序

代码实例

c++实现

//快速排序算法,输入是一个数组,输出也是一个数组
//函数设计,参数为一个vector,无返回值,参数既是输出也是输出,第二个参数表示这个vector的索引
//第三个参数是vector的右索引
/**测试用例:*1.只有一个元素*2.包含2个元素*3.包含多个元素,元素按从小到大顺序排列*4.包含多个元素元素从大小顺序排列*5.包含多个元素,顺序无序*6.包含多个元素,元素都相同***/
void MyQsort(std::vector<int>& vector)
{//如果只有一个元素,无需进行排序,这是基线条件if(vector.size() <=1 )return;int value = vector[0];std::vector<int> leftVec;  //用于存储左侧比value小的数值std::vector<int> rightVec;  //用于存储右侧比value大的数值for(int i = 1; i < vector.size(); i++){if(vector[i] >= value)rightVec.push_back(vector[i]);elseleftVec.push_back(vector[i]);}MyQsort(leftVec);  //比该数值小的进行快速排序,成为分解为子问题MyQsort(rightVec);  //比该数值大的进行快速排序,成为分解为子问题vector.clear();vector.insert(vector.begin(), leftVec.begin(), leftVec.end());vector.push_back(value);vector.insert(vector.end(), rightVec.begin(), rightVec.end());return;
}

 python实现

import osdef my_qsort(lst):length = len(lst)if length <= 1:return lstvalue = lst[0]leftLst = [x for x in lst[1:] if x < value]rightLst = [x for x in lst[1:] if x >= value]leftLst = my_qsort(leftLst)rightLst = my_qsort(rightLst)lst = leftLst+[value]+rightLstprint(f'--lst={lst}')return lstlst = [5,2,3,8,1,7]
lst = my_qsort(lst)
print(f'lst={lst}')#输出
--lst=[1, 2, 3]
--lst=[7, 8]
--lst=[1, 2, 3, 5, 7, 8]
lst=[1, 2, 3, 5, 7, 8]

时间复杂度分析

快速排序的时间复杂度分析,利用二叉树来分析快速排序的时间复杂度更容易理解。

结合前面的算法实现,可以发现如下的规律:

  1. 假设待排序的数组中有个n个数值,递归的第一层作为二叉树的根节点,再这一层中有一个for循环遍历了n次,所以设这个节点的值为n;同时递归的首层分出了两个子数组,将这两个子树作为根节点的两个子节点,并且这两个字子节点的和是n
  2. 两个子节点每个都做一个新的二叉树的根节点,然后继续生成的新的子节点,但是有一个规律即两个子节点的和都等于根节点的值。
  3. 由此可以得出一个结论二叉树每一层的和都是n
  4. 要求这棵二叉树中所有节点值的和就是时间复杂度

这个问题就转变成了一棵二叉树问题,现在求解二叉树的最好时间复杂度变成了如何求解二叉树如何分布时间复杂度最低;求解最差时间复杂度变成了求解二叉树如何分布时间复杂度最高。

最佳时间复杂度

最佳的时间复杂度问题变成了,每次分区都将数组分成平均相等的两份,请看下面的图片:

由图可知二叉树的每一层的节点的和为n,那么要求所有二叉树节点的和需要知道树的高度:

树的高度:h = logn

因为每一层都是上一层数值的1/2。

现在知道了树的高度,那么最佳的时间复杂度为:

最佳时间复杂度 = h * n=O(nlogn) 

最差时间复杂度

最差的时间复杂度就需要求解二叉树如何分布,可以使得所有节点的和最大。那只有数组分区时极度不平衡,那么每次数据在一边。如下图所示:

这是时候变成了:最差时间复杂度 = n + (n-1) + (n-2) + ...+1=(n+1)*n/2=O(n^{2})

空间复杂度分析

最佳空间复杂度

递归函数的空间复杂度一般将函数栈作为一个空间单位,因为一个函数栈包含了临时变量、参数等。占用函数栈个数最少的二叉树分布就是最佳空间复杂度。那么怎么理解空间复杂度最低呢?答案是使的二叉树的高度最低,那么数组每次如何分布才能最低呢?那只有二叉平衡树高度最低了。即每次数组分区按照平均分配的方法进行分区。

最佳空间复杂度 = 最短的树的高度 = O(logn)

最差时间复杂度

同理,最差的时间复杂度肯定递归调用同时占据最多个函数栈空间的就是最差空间复杂度。

最差空间复杂度 = 最大的二叉树高度 = O(n)

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

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

相关文章

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的电脑本地部署一下DeepSeek试试&#xff0c;由于不希望污染电脑的Windows环境&#xff0c;所以在wsl中安装了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安装了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

题解 | 牛客周赛82 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 判断字符串第一个字符和第三个字符是否相等 import java.io.*; import java.math.*; import java.u…

Codeforces Round 1007 (Div. 2)(ABCD1)

A. The Play Never Ends 翻译&#xff1a; 让我们来介绍一种双人游戏--乒乓球&#xff0c;在这种游戏中&#xff0c;胜负永远分明&#xff0c;不可能出现平局。 索赛、福福和浩海三人想用一生的时间打乒乓球。他们决定用以下方式永远打下去&#xff1a; 在每场比赛中&#xff…

swift 开发效率提升工具

安装github copliot for xcode github/CopilotForXcode brew install --cask github-copilot-for-xcode安装swiftformat for xcode brew install swiftformatXcode Swift File代码格式化-SwiftFormat

蜂鸣器使用

1、蜂鸣器原理 无源蜂鸣器模块根据输入的 不同方波信号&#xff08;作为震荡源&#xff09;可以发出不同的声音。驱动电路中三极管电阻一般为1K-4K都行&#xff0c;能够让三极管导通即可。&#xff08;三极管即带箭头的部分&#xff0c;基极和发射机&#xff08;PNP&#xff09…

drawDB:一款免费数据库设计工具

drawDB 是一款基于 Web 的免费数据库设计工具&#xff0c;通过拖拽、复制、粘贴等方式进行数据库建模设计&#xff0c;同时可以生成相应的 SQL 脚本。 功能特性 drawDB 目前可以支持 MySQL、MariaDB、PostgreSQL、SQL Server 以及 SQLite 数据库&#xff0c;核心功能包括&…

【AI论文】将1568个标记压缩到单个向量中并再解压:探索嵌入空间容量的极限

摘要&#xff1a;近期&#xff0c;一系列研究致力于解决将标记序列压缩为更短的实值向量序列的问题&#xff0c;这些向量序列将作为输入&#xff0c;替代标记嵌入或键值缓存。这些方法有助于减少现有语言模型中的计算量。尽管使用了强大的模型作为编码器&#xff0c;但无损压缩…

【JavaWeb学习Day20】

Tlias智能学习系统 员工登录 三层架构&#xff1a; Controller&#xff1a;1.接收请求参数&#xff08;用户名&#xff0c;密码&#xff09;2.调用Service方法3.响应结果 具体实现&#xff1a; /*** 登录*/ ​ PostMapping("/login") public Result login(Reque…

.net开源商城_C#开源商城源码_.netcore开源商城多少钱

在现今的电子商务领域&#xff0c;开源商城系统为企业和开发者提供了丰富的选择和可能性。其中&#xff0c;.NET开源商城、C#开源商城源码以及.NET Core 开源商城备受关注。然而&#xff0c;对于这些开源商城的价格问题&#xff0c;往往是人们在选择时需要重点考虑的因素之一。…

Java并发编程之ConcurrentHashMap的原理和使用

ConcurrentHashMap(CHM)是Java为解决高并发场景下哈希表性能瓶颈而设计的线程安全容器,其核心目标在于: 线程安全‌:避免多线程操作导致的数据不一致问题‌;高吞吐量‌:通过细粒度锁和无锁化设计降低线程竞争‌;动态扩展‌:支持自动扩容与数据结构优化(如链表转红黑树…

问题修复-后端返给前端的时间展示错误

问题现象&#xff1a; 后端给前端返回的时间展示有问题。 需要按照yyyy-MM-dd HH:mm:ss 的形式展示 两种办法&#xff1a; 第一种 在实体类的属性上添加JsonFormat注解 第二种&#xff08;建议使用&#xff09; 扩展mvc框架中的消息转换器 代码&#xff1a; 因为配置类继…

《基于 LIME 的低照度图像处理》开题报告

目录 一、研究目的和意义 1.研究目的 2.研究意义 二、国内外研究现状和发展趋势 三、研究内容、研究方法及可行性分析 1、研究内容 2、研究方法 3、可行性分析 四、项目特色与创新点 1、面向特定应用场景的针对性研究 1.多算法比较与选择的严谨性 2.基于硬件平台的深…

【Linux文件IO】系统IO详情

目录 一、前言 二、相关API介绍 2.1 open 2.2 read 2.3 write 2.4 lseek 2.5 close 三、简单示例 3.1 示例1 3.2 示例2 一、前言 在 Linux 系统编程中&#xff0c;系统 I/O&#xff08;又称低级 I/O&#xff09;是直接通过操作系统提供的系统调用实现的文件操作接口…

MATLAB代码:机器学习-分类器

本文包含三种机器学习分类器的MATLAB实现方式代码块&#xff1a;支持向量机、决策树、逻辑回归。 目录 SVM/支持向量机(Support Vector Machine) 原理 MATLAB实现 实例代码块 采用搜索确定参数 Decision Tree / 决策树 原理 MATLAB实现 实例代码块 Logistic Regressio…

DeepSeek赋能数据治理:数字转型智慧引擎,企业数治的全新解决方案

在数字化时代&#xff0c;数据已成为企业的核心资产&#xff0c;而数据治理则是企业实现数字化转型的关键环节。然而&#xff0c;传统数据治理面临着诸多挑战&#xff0c;如数据孤岛、数据质量参差不齐、治理效率低下等。 如今&#xff0c;随着人工智能技术的飞速发展&#xf…

火山引擎AI一体机-DeepSeek版来了

2025年伊始&#xff0c;DeepSeek 在各领域尽显其能。除常态公有云部署外&#xff0c;一些企业也希望将 DeepSeek 与本地数据、业务场景相融合&#xff0c;拥抱 AI 新未来。不过&#xff0c;算力基础设施缺失、模型交付周期长、推理性能不足、数据安全合规等技术和成本问题成为了…

Hadoop之02:MR-图解

1、不是所有的MR都适合combine 1.1、map端统计出了不同班级的每个学生的年龄 如&#xff1a;(class1, 14)表示class1班的一个学生的年龄是14岁。 第一个map任务&#xff1a; class1 14 class1 15 class1 16 class2 10第二个map任务&#xff1a; class1 16 class2 10 class…

IP属地是通过卫星定位的吗?如何保护用户隐私

在数字时代&#xff0c;网络空间成为了人们日常生活不可或缺的一部分。随着社交媒体、在线服务等平台的兴起&#xff0c;用户IP属地信息的重要性日益凸显。然而&#xff0c;关于IP属地是如何确定的&#xff0c;尤其是是否通过卫星定位这一问题&#xff0c;却常常引发公众的疑问…

20250225-代码笔记03-class CVRPModel AND other class

文章目录 前言一、class CVRPModel(nn.Module):__init__(self, **model_params)函数功能函数代码 二、class CVRPModel(nn.Module):pre_forward(self, reset_state)函数功能函数代码 三、class CVRPModel(nn.Module):forward(self, state)函数功能函数代码 四、def _get_encodi…

操作系统之文件系统

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…