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

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

【位运算】消失的两个数字(hard)

消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...