当前位置: 首页 > 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…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

LLMs 系列实操科普(1)

写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四&#xff…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...