【算法练习】30:快速排序学习笔记

一、快速排序的算法思想

        原理:快速排序基于分治策略。它的基本思想是选择一个元素作为“基准”,将待排序序列划分为两个子序列,使得左边的子序列中的所有元素都小于基准,右边的子序列中的所有元素都大于基准。这个划分操作被称为分区。然后,对左右两个子序列分别递归地执行快速排序,直到整个序列有序。

        分区操作的关键在于确定基准元素在最终排序位置上,而它两侧的元素满足上述大小关系。实现时,可以通过一次遍历,将小于基准的元素交换至基准左侧,大于基准的元素交换至其右侧。这样,基准元素自然就落在了正确的位置上。

        时间复杂度:最好情况是当每次分区都能均匀划分数组,即每次划分后左右子数组的长度相差不大时,快速排序的时间复杂度为 O(n log n)。平均情况时间复杂度也为 O(n log n)最坏情况下当待排序数组已经是有序或接近有序时,每次分区只能得到一个子数组为空、另一个包含所有元素的情况,此时时间复杂度退化为O(n^2)

        空间复杂度:快速排序是一种递归算法,递归调用过程中需要使用栈来保存中间状态。在最坏情况下,递归深度为 n (完全不平衡的划分),因此空间复杂度为 O(n)。然而,实际应用中通过合理选择基准值和采用尾递归优化,递归深度往往远小于 n,平均空间复杂度接近 O(log n)

        稳定性:不稳定,在分区过程中,相等的元素可能会因为与基准元素的相对位置改变而发生相对顺序的改变,导致排序后相等元素的顺序与原始顺序不一致。

二、快速排序的算法步骤

  1. 选择基准:从待排序序列中选择一个元素作为基准。通常可以选择数组的第一个元素、最后一个元素、中间元素或随机元素。

  2. 分区:遍历待排序序列,将所有小于基准的元素交换到基准之前,所有大于基准的元素交换到基准之后。最后将基准元素放置在其最终位置上,此时基准左侧元素均小于基准,右侧元素均大于基准。

  3. 递归排序:对基准左侧(小于基准的子序列)和右侧(大于基准的子序列)分别递归执行快速排序。

        本文是自己的算法学习笔记,这里超级推荐一个开源算法项目,链接我放在这里了!非常感谢开源大佬:《hello算法》快速排序

 

三、基于Python的快速排序实现

def quicksort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) // 2]  # 选择中间元素作为基准left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]  # 包含相等元素的子序列,保持稳定性right = [x for x in arr if x > pivot]return quicksort(left) + middle + quicksort(right)# 示例
arr = [5, 2, 4, 6, 1, 3]
sorted_arr = quicksort(arr)
print(sorted_arr)  # 输出: [1, 2, 3, 4, 5, 6]

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

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

相关文章

在k8s 中部署有状态服务MongoDB高可用集群详解(附带镜像)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、k8s简介 2、MongoDB介绍 3、为什么要…

新手开抖店不出单?三种方法解决“没曝光,没流量”难题!

哈喽~我是电商月月 新手开抖店经常会这样做&#xff1a;开通后选品上架。然后傻傻的等待流量进来&#xff0c;然后每天就是刷新再刷新&#xff1f;最后还是没流量&#xff01; 我敢说这样做你两个月也出不了单&#xff0c;方法错误&#xff0c;再好的产品也卖不出去&#xff…

C++内存管理和模板

一、内存管理 关键字&#xff1a;new delete 我们知道&#xff0c;在C语言中内存的开辟和修改&#xff0c;要用到函数malloc/calloc等&#xff0c;而且要直自己判断内存开辟是否正确&#xff0c;所以在C中&#xff0c;提供了两函数&#xff1a;new/delete 由于malloc无法很…

【我的代码生成器】生成React页面类

有了数据表的结构信息&#xff0c;就能生成React 的页面类&#xff0c;快捷方便。 生成界面如下&#xff1a; 生成的React FrmUser.js页面如下&#xff1a; 只需再写里面的操作逻辑代码。

婴儿专用洗衣机有必要买吗?四大宝藏婴儿测评对比

幼龄时期的宝宝的衣物&#xff0c;是比较需要注意的时候。可能一不注意宝宝穿在身上就会有不适宜症状发生。所以宝妈们真的要随时观察&#xff0c;然后在宝宝洗衣服的这上面多下点功夫&#xff0c;不要让宝宝受到这种无谓的伤害。小婴儿的抵抗力比我们差很多。有些细菌、病毒可…

探索未来:智能客服产品架构的演进与创新

随着科技的迅猛发展和人工智能技术的不断成熟&#xff0c;智能客服已经成为了现代企业提供客户服务的重要方式。而智能客服产品的架构设计则直接影响着其在实际运营中的效果和用户体验。本文将探讨智能客服产品架构的演进历程以及未来的创新趋势。 1. 传统客服架构的局限性 传…

数据结构__顺序表

概念及结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改 需要用到数组&#xff1a;数组的绝对优势&#xff1a;下标的随机访问&#xff08;因为物理空间连续&#xff09; a[i]等…

Linux下使用C语言实现线程池---代码及分析

线程池 相关文章 协议 Socket编程 高并发服务器实现 线程池 如果一个客户端建立连接使用创建一个线程用于处理这一个线程, 处理结束的时候把这一个线程删除, 这个时候会导致线程的创建以及销毁会消耗大量的时间 这时候可以一次性创建多个线程, 这几个线程统称线程池, 如果客户…

spark实验三-spark进阶编程

1&#xff0e;Spark编程统计各地区租房人数 实验目标&#xff1a; (1) 掌握在IntelliJ IDEA 中操作spark程序开发 (2) 打包程序提交集群运行 实验说明&#xff1a; 现有一份某省份各地区租房信息文件 house.txt&#xff0c;文件中共有8个数据字段&#xff0c;字段说明…

更改ip地址的几种方式有哪些

在数字化时代&#xff0c;IP地址作为网络设备的标识&#xff0c;对于我们在网络世界中的活动至关重要。然而&#xff0c;出于多种原因&#xff0c;如保护隐私、访问特定网站或进行网络测试&#xff0c;我们可能需要更改IP地址。虎观代理将详细介绍IP地址的更改方法与步骤&#…

基于Java停车场管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

欢乐钓鱼大师秒杀源码

gg修改器设置里面单选a内存然后去试试e类型搜索鱼竿的拉杆速度然后点修改点很多增加1然后游戏返回在进去看鱼竿拉速然后在修改器的里面找到拉速一样的数值其他恢复全移除不恢复移除会闪退然后点开保留下来的拉速数值点转到会有一堆数值你得找里面找到鱼竿的伤害距离等数值就可以…