当前位置: 首页 > news >正文

数据结构(邓俊辉)学习笔记】排序 2——快速排序:性能分析

文章目录

  • 1. 不稳定 + 就地
  • 2. 最好情况 + 最坏情况
  • 3.平均情况

1. 不稳定 + 就地

以下针对刚才所给出的快速排序算法的第一个版本,就其性能做一分析。

首先很遗憾地发现,这个算法是不稳定的。快速排序算法的不稳定性通过我们刚才所举的那个实例可以清楚地看出来。
在这里插入图片描述
注意到,在原始的输入序列中有两个5,按照先后次序,我们分别用5A 和5B 来表示。

在经过一次划分之后,我们可以看到这两个元素的位置已经彼此颠倒。实际上这种现象必然是普遍存在的。因为对于任何两个小于候选轴点的元素而言,它们加入子序列 L 的次序必然是颠倒的。同理对于大于候选轴点的雷同元素而言,也有对称的性质。

其次整个算法也是可以就地实现的,也就是说它只需要常数的附加空间。这一点从刚才这组原理和过程图中也可以清晰地看出。
在这里插入图片描述
实际上除了原始的输入序列,我们这里只需要维护常数个指针以及用于保存候选轴点的一个单元。

2. 最好情况 + 最坏情况

在这里插入图片描述

那么整个算法的运行时间呢?我们知道,对于归并排序而言,整个算法的运行时间可以保证不超过 n*log n。我们也知道其关键在于归并排序可以保证任何一对被划分出来的子任务在规模上都是彼此相当的,也就是规模都接近二分之N。因此总体的运行时间也就是求解两个这样的问题,再加上为了将它们的结果合并所需要的线性时间。

很遗憾,快速排序算法却不能像归并排序算法那样保证子任务划分时的均衡性。实际上partition 算法的每次划分结果与其说是取决于这个算法,不如说取决于最初选定的候选轴点

如果候选轴点在最终有序列中所对应的秩为 r,那么经划分之后所得到的序列 L 的长度也必然就是 r。而对应的子序列 G 的长度也必然为 n 减 1 再减 r。划分的结果是否均衡完全取决于我们的运气。

  • 在最好的情况下,我们的每次划分都是均衡的,或者至少是接近均衡的,于是我们自然可以达到最优的 n*logn。

  • 然而反过来,在最坏的情况下,有可能我们的每一次划分都不均衡,甚至极不均衡。比如最为极端的一种情况就是,每一个候选节点都是在当前而言最小或者最大的极值元素,以至于在划分之后,子序列 L 为空或者 G 为空。也就是说,在我们所划分出来的一对子任务中,总是有一个规模为零,而另一个相对于此前的规模只减少了一个单位。

    根据这个递推式不难解出,此时算法所需要的总体运行时间必然是平方量级的。也就说与起泡排序等低级算法居然性能是相当的。

当然采用一些简明的策略,在付出足够小的代价之后,我们的确可以在一定程度上降低最坏情况出现的概率。比如我们可以采用所谓随机选取法,也就说不再是每次都固定地将首元素作为候选轴点。而是在整个序列中,随机地选择其一。另一种更为有效的方法是所谓的三者取中法,也就是说我们每次都是在整个序列中随机地抽取3个元素,然后将其中数值居中的那个作为候选轴点。

当然,无论采用什么方法,我们也只能是在一定程度上降低最坏情况出现的概率,而无法根本的杜绝最坏情况的出现。既然如此,我们接下来不得不回答的一个问题就是,就基本的快速排序算法而言,其平均性能又有多高呢?

3.平均情况

非常幸运的是,以上基本的快速排序算法在常规的随机意义下,平均性能的确可以达到最优的 n log n。
在这里插入图片描述

以下我们不妨针对最为常见的均匀独立分布来做一精确的估算,也就说我们在这里假设,所有的元素都是均匀的取自于某一个数值范围。同时各元素在确定各自取值时是互不依赖的

我们来考察任何一个这样的随机序列,调用 partition 算法对它进行的划分将有几种可能呢?无非 n 种可能,具体的哪种情况完全取决于最初所选定的那个候选轴点。

更准确地讲,是这个候选轴点在最终有序列中所具有的秩。如果将候选轴点的这个秩记作 k,那么 partition 算法所输出的子序列 L 长度也应该是 k,这个子序列所对应的那个子任务所需的平均运行时间也因此就可以表示为Tk。对称的 partition 算法所输出的子序列 G 长度应该为 n 减 k 减1,这个子序列所对应的那个子任务从递归的角度来看,所需要的平均运行时间也因此可以表示为 T n 减 k 再减1。这样的一对排序子任务总共所需要的运行时间也自然就是二者之和。

进一步的,既然按照假设这里服从均匀独立分布,因此各种情况出现的概率应该均等。具体来说都是 n 分之1。因此所有这些情况所对应的平均运行时间,也就是用这个概率对它们的总和进行平均。以下的分析,焦点就会聚在这个求和号上。尽管这个求和涉及到前后两个序列,但是略加观察之后,我们不难发现,这两个序列的求和应该完全是相等的,你能看出原因来吗?

没错,这两个序列的取值范围都是从 0 到 n 减1 ,只不过前者是递增的,从0到 n 减1,而后者只不过是递减的,从 n 减1到0。因此我们只需保留其中的一项,同时作为补偿将它的系数加倍。

接下来我们将这个等式的两端同时乘以 n,于是就可以得到这样一个等式。如果将其中所有的 n 都替换为 n 减1,我们又可以进而得到下面这个等式。现在我们只需将这两个等式相减,就可以得到这样一个等式。除了系数,这个等式主要都包含一个 Tn 以及两个 T n 减一。

接下来我们只需对 Tn 和 Tn 减1合并同类项,就可以得到这样一个等式。对于这样一个等式,我们不妨令它的左右两端同时除以 n 以及 n 加1。

于是就可以得到这样一个等式,如果我们将这个等式的左侧表示和理解为另一个函数 Sn,那么右侧的这一项也就对应于 Sn 减1。这样我们也得到了一个关于 Sn 的简明递推式。

因此接下来,我们可以进而将右侧的 Sn 减 1 替换为 Sn 减2。当然,为此我们需要追加一项,这种地推可以持续进行下去,也就说我们可以将 Sn 减2替换为 Sn 减3,再将 Sn 减3替换为 Sn 减4以及 Sn 减4替换成 Sn 减5,诸如此类。

在递推到最终一步之前,我们所引入的各项将构成一个级数。你应该看得出来这是一个什么级数。没错,调和级数。我们在第一章就曾介绍过,就渐进意义而言,调和级数是与自然对数 log n 同阶的。

由此可见,我们这里所需要估计的快速排序算法的平均运行时间在渐进意义下的确不超过 n * log n,那么它对应的常系数呢?为此,我们只需将 log n 替换为以2为底的对数,相应的也自然可以得知常系数应为两倍的 ln2,具体来说也就大致为1.39。

这样小的一个长系数,也保证了快速排序算法在通常情况下的优异性能,也就是说,快速排序的确名符其实。

相关文章:

数据结构(邓俊辉)学习笔记】排序 2——快速排序:性能分析

文章目录 1. 不稳定 就地2. 最好情况 最坏情况3.平均情况 1. 不稳定 就地 以下针对刚才所给出的快速排序算法的第一个版本,就其性能做一分析。 首先很遗憾地发现,这个算法是不稳定的。快速排序算法的不稳定性通过我们刚才所举的那个实例可以清楚地看…...

在postman中使用javascript脚本生成sign签名

大多数线上api接口服务都需要提供签名才可以正常访问。虽然带来了安全,单有时为了快速验证接口的某个功能,就不得不编写代码,计算签名然后再请求。那么,使用postman提供的script功能,是否能实现签名计算功能吗&#xf…...

设计模式—2—单例模式

文章目录 一、单例模式概述二、单例模式特点三、示例3.1、基本实现(懒汉式-线程不安全)3.2、基本实现(懒汉式-线程安全)3.3、基本实现(饿汉式) 四、总结 一、单例模式概述 单例模式(Singleton …...

服务器数据恢复—磁盘坏扇区导致raid6阵列崩溃的数据恢复案例

服务器存储数据恢复环境: 一台存储中有一组由12块SAS硬盘组建的raid6磁盘阵列,划分了1个卷,由数台Vmware ESXI主机共享存储。卷中存放了大量的Windows系统虚拟机。这些虚拟机系统盘大小一致,数据盘大小不确定,数据盘都…...

原码、反码、补码

目录 背景: 1.原码 举例: 2.反码: 举例 : 3.补码: 举例: 背景: 在计算机科学中,原码、反码和补码是三种用于表示有符号整数(即包含正负数) 的二进制编码方式。它们各自有其独特的定义和用途&#x…...

排序算法之计数排序详细解读(附带Java代码解读)

计数排序(Counting Sort)是一种非比较型的排序算法,它通过统计每个元素的出现频率,然后计算元素的位置信息,最后将元素放到正确的位置,从而实现排序。计数排序特别适用于元素范围有限的情况,比如…...

Linux:如何使用 Crontab

今天想了解一下Linux Crontab。嗯,在Windows上,可以看做和定时任务差不多。 “要在特定时间进行特定工作。” 如果是这样,可以使用crontab,轻松使用Linux。 1. 基本 (crontab basic) 先看一下基本的crontab使用方法吧。在Linu…...

AI模型:追求全能还是专精?-- 之7 智能工厂程序设计

Q1、感觉上上面离我想做的事情却来越远了。我们跳过讨论直接进入程序设计吧。StringProcessor(文字/信息/数字)抽象代理工厂-创造 Universal given时空区域 |bar PROCESS: 页面版块的图式schema/概念的KE图式CaseFilter 一般应用工厂-制造- General sign…...

如何在本地服务器部署SeaFile自托管文件共享服务结合内网穿透打造私有云盘?

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 下载安装3.2 Cpolar注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍,如何使用两个简单软件…...

学习记录:js算法(二十五):合并两个有序链表

文章目录 合并两个有序链表我的思路网上思路 总结 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 图一 示例 1:(如图一) 输入:l1 [1,2,4], l2 [1,3,4] …...

43. 1 ~ n 整数中 1 出现的次数【难】

comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9843.%201%EF%BD%9En%E6%95%B4%E6%95%B0%E4%B8%AD1%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0/README.md 面试题 43. 1 ~ n 整数中 1 …...

K8S - 理解volumeMounts 中的subpath

在上一篇文章中 springboot service如何动态读取外部配置文件 介绍了springboot 中如何实时读取外部配置文件的内容 部署在K8S 接下来我把它部署在k8s 首先, 我们把配置文件放入项目某个目录 这步部是必须的, 毕竟我们要引入是项目外部的文件&#xf…...

java工程师成功转型大数据

时间:2024年09月06日 作者:小蒋聊技术 邮箱:wei_wei10163.com 微信:wei_wei10 音频:喜马拉雅 希望大家帮个忙!如果大家有工作机会,希望帮小蒋推荐一下,小蒋希望遇到一个认真做事…...

visual studio 2022更新以后,之前的有些工程编译出错,升级到Visual studio Enterprise 2022 Preview解决

系列文章目录 文章目录 系列文章目录前言一、解决方法 前言 今天遇到一个问题:visual studio 2022升级成预览版以后,之前的有些工程编译出错。首先代码、项目设置都没有改变,只是更新了visual studio 2022。 在编译工程时,编译器…...

Linux 性能调优技巧

1理解 Linux 性能的基本组成 CPU 使用率:衡量 CPU 在单位时间内被占用的程度。内存使用:关注的是活跃内存与缓存内存的比例,以及是否有过多的交换。I/O 性能:磁盘读写速度直接影响应用程序的响应时间和吞吐量。网络性能&#xff…...

【网络安全】WordPress Uncontrolled Resource Consumption

未经许可,不得转载。 文章目录 WordPresswp-cron.php实战漏洞危害解决措施WordPress WordPress 是全球最广泛使用的内容管理系统(CMS),目前约有 43% 的网站依赖于它。由于其用户友好的界面和丰富的插件功能,WordPress 成为了全球最受欢迎的 CMS。 然而,在使用 WordPres…...

gitee绑定公钥后依旧无法使用_gitee push添加公钥无效

解决: 步骤按照官网操作即可:gitee官方说明 看看远程地址是否使用的http模式,是的话换ssh模式...

Linux 删除 当前下的 mysql-8.0.31 空文件夹

在Linux中,如果你想要删除当前目录下的名为mysql-8.0.31的空文件夹(即该文件夹内没有任何文件或子文件夹),你可以使用rmdir命令。但是,如果mysql-8.0.31文件夹并非完全为空(即它包含文件或子文件夹&#xf…...

2024,中国服务器操作系统迎云智主升浪

“主升浪”描述了股市中一轮行情中涨幅最大、上升持续时间最长的阶段。2024年,云与AI深度融合形成了数字经济主升浪,从而打开了中国服务器操作系统的黄金机遇期。 2024年注定将成为非常不平凡的一年。不仅是实现“十四五”规划目标任务的关键一年&#x…...

STM32快速复习(九)RTC时钟模块

文章目录 前言一、RTC是什么?RTC的工作原理?二、库函数以及示例1.标准库函数2.示例代码 总结 前言 STM32 的实时时钟(RTC)是一个独立的定时器。 STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下&#xf…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Linux入门(十五)安装java安装tomcat安装dotnet安装mysql

安装java yum install java-17-openjdk-devel查找安装地址 update-alternatives --config java设置环境变量 vi /etc/profile #在文档后面追加 JAVA_HOME"通过查找安装地址命令显示的路径" #注意一定要加$PATH不然路径就只剩下新加的路径了,系统很多命…...

【向量库】Weaviate概述与架构解析

文章目录 一、什么是weaviate二、High-Level Architecture1. Core Components2. Storage Layer3. 组件交互流程 三、核心组件1. API Layer2. Schema Management3. Vector Indexing3.1. 查询原理3.2. 左侧:Search Process(搜索流程)3.3. 右侧&…...

Springboot多数据源配置实践

Springboot多数据源配置实践 基本配置文件数据库配置Mapper包Model包Service包中业务代码Mapper XML文件在某些复杂的业务场景中,我们可能需要使用多个数据库来存储和管理不同类型的数据,而不是仅仅依赖于单一数据库。本技术文档将详细介绍如何在 Spring Boot 项目中进行多数…...

2025-06-08-深度学习网络介绍(语义分割,实例分割,目标检测)

深度学习网络介绍(语义分割,实例分割,目标检测) 前言 在开始这篇文章之前,我们得首先弄明白,什么是图像分割? 我们知道一个图像只不过是许多像素的集合。图像分割分类是对图像中属于特定类别的像素进行分类的过程,即像素级别的…...