交换排序——快速排序
交换排序——快速排序
- 7.7 交换排序——快速排序
- 快速排序概念
- c语言的库函数qsort
- 快速排序框架quickSort
7.7 交换排序——快速排序
快速排序概念
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法(下文简称快排),其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左、右子序列分别重复该过程,直到所有元素都排列在相应位置上为止。
虽然快排是Hoare发明的,但Hoare并没有用自己的名字去给这个算法命名,而是用快速来对这个排序命名,用于彰显这个排序算法的特点:快。
例如我们设基准值为div,则排序的目的是为了完成这个目标:
这个是二叉树结构的交换排序,所以div左边和div右边的区间还要分别重复这个过程。
c语言的库函数qsort
c语言中就有一个库函数qsort:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
它的4个参数表示的含义:
- base:被用来排序的数组的数组名或数组的首元素地址。
- num:数组的元素个数。
- width:数组的单个元素占用的内存大小。
- compare:程序员自定义的比较函数。
用户自定义的比较函数需要返回两个元素之间的差值。这很大程度上局限了这个函数的玩法(比如实现自定义类型数组的排序可能会比较麻烦)。但这个函数的底层实现就是快速排序,比一般的排序算法的速度要快。
应用实例:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>typedef int Datatype;//用户自定义的比较函数
int cmp(const void* a, const void* b) {//升序排序return (*(Datatype*)a) - (*(Datatype*)b);//这个函数通过差值判断是否交换
}void f() {srand((size_t)time(0));//随机数的种子Datatype a[30] = { 0 };int i = 0;for (i = 0; i < 30; i++) {a[i] = rand() % 100 + 1;//生成随机数printf("%d ", a[i]);}printf("\n");//四个形参分别是数组名,要排序的元素个数,单个元素的大小,程序员自定义的比较函数qsort(a, sizeof(a)/sizeof(a[0]), sizeof(Datatype), cmp);for (i = 0; i < 30; i++)printf("%d ", a[i]);
}int main() {f();return 0;
}
快速排序框架quickSort
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void quickSort(Datatype* array, int left, int right)
{if (right - left <= 0)//区间只有1个值或区间不存在时没必要继续分return;// 按照基准值对array数组的 [left, right)区间中的元素进行划分int keyi = partSort(array, left, right);// 划分成功后以keyi为边界形成了左右两部分 [left, keyi) 和 [keyi+1, right)// 递归排[left, div)quickSort(array, left, keyi - 1);// 递归排[div+1, right)quickSort(array, keyi + 1, right);
}
上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,我们在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
虽然快速排序性能很优异,但并不是所有情况快排都是最优选。甚至数据量小的情况比如10个数据,快排对这10个数据排序,耗时说不定比插入排序慢。我们学习排序是为了能判断所有情况,并根据情况选择合适的排序算法来处理数据。
10个数据组成的数组看成完全二叉树就是4层,递归的话还要多调用3次函数,每次调用函数都要向内存申请空间,加大时间和空间的成本。
若使用插入排序来处理这种数量比较小的数据,则减少了多余的递归调用。能使排序完成时间缩短。
以满二叉树为例子,最底层占 50 % 50\% 50%的结点,后层数网上逐级减半,3层的优化效率就是
50 % + 25 % + 12.5 % = 87.5 % 50\%+25\%+12.5\%=87.5\% 50%+25%+12.5%=87.5%。
虽然我们不知道这个优化效率是怎么算出来的,但是我们可以通过高精度计时库来计算10个元素时两种排序的耗时。参考程序如下(c++程序):
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<stdlib.h> #include<stdbool.h> #include<chrono> #include<iostream> using namespace std;typedef int Datatype;int cmp(const void* a, const void* b) {return (*(Datatype*)a) - (*(Datatype*)b); }void insertSort(Datatype* a, int n) {int i = 0;for (i = 0; i < n - 1; i++) {int end = i;int tmp = a[i + 1];while (end >= 0)if (a[end] > tmp) {a[end + 1] = a[end];--end;}else break;a[end + 1] = tmp;} }void f() {srand((size_t)time(0));Datatype a[10], b[10];int i = 0;for (i = 0; i < 10; i++) {a[i] = rand() % 1000 + 1;b[i] = a[i];}auto begin = std::chrono::high_resolution_clock::now();qsort(a, 10, 4, cmp);//用快排对10个数据进行排序auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> time1 = end - begin;std::cout << time1.count() << endl;auto begin2 = std::chrono::high_resolution_clock::now();insertSort(b, 10);//用插入排序对10个数据进行排序auto end2 = std::chrono::high_resolution_clock::now();std::chrono::duration<double> time2 = end2 - begin2;std::cout << time2.count() << endl;//如果快排用时比插入排序用时长,则输出1,否则输出0cout << (time1.count() - time2.count() > 1e-15) << endl; }int main() {f();return 0; }
chrono
库的high_resolution_clock
可以提供高精度的时间点,通过计算两个时间点的差值来得到代码执行的时间间隔,duration<double>
用于以秒为单位表示时间间隔,count()
函数返回该时间间隔的值。用大量数据时表现不好,小量数据时表现优异的算法处理这种小规模数据的优化方式,有人称作小区间优化。这种优化的本质是一种锦上添花的行为,无法改变算法本身的弊端。
到这里为冒泡排序惋惜1秒钟,我确实没遇到过最适合冒泡排序的应用场景。
关于partSort
函数的实现,因为内容太多,分成几篇来写。
相关文章:
交换排序——快速排序
交换排序——快速排序 7.7 交换排序——快速排序快速排序概念c语言的库函数qsort快速排序框架quickSort 7.7 交换排序——快速排序 快速排序概念 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法(下文简称快排),其基本思想为&a…...
nodejs入门(1):nodejs的前后端分离
一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的,当然,我肯定是很多年的计算机基础的,万变不离其宗。 现在web网站都流行所谓的前后端结构,不知不觉我也开始受到这个影响,以前都是前端直接操作…...
笔记|M芯片MAC (arm64) docker上使用 export / import / commit 构建amd64镜像
很简单的起因,我的东西最终需要跑在amd64上,但是因为mac的架构师arm64,所以直接构建好的代码是没办法跨平台运行的。直接在arm64上pull下来的docker镜像也都是arm64架构。 检查镜像架构: docker inspect 8135f475e221 | grep Arc…...
gorm框架
连接 需要下载mysql的驱动 go get gorm.io/driver/mysql go get gorm.io/gorm 约定 主键:GORM 使用一个名为ID 的字段作为每个模型的默认主键。表名:默认情况下,GORM 将结构体名称转换为 snake_case 并为表名加上复数形式。 例如…...
免费送源码:Java+Springboot+MySQL Springboot多租户博客网站的设计 计算机毕业设计原创定制
Springboot多租户博客网站的设计 摘 要 博客网站是当今网络的热点,博客技术的出现使得每个人可以零成本、零维护地创建自己的网络媒体,Blog站点所形成的网状结构促成了不同于以往社区的Blog文化,Blog技术缔造了“博客”文化。本文课题研究的“…...
【ASR技术】WhisperX安装使用
介绍 WhisperX 是一个开源的自动语音识别(ASR)项目,由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型,通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别(large-v2 为 70 倍实时…...
【计算机网络】协议定制
一、结构化数据传输流程 这里涉及协议定制、序列化/反序列化的知识 对于序列化和反序列化,有现成的解决方案:①json ②probuff ③xml 二、理解发送接收函数 我们调用的所有发送/接收函数,根本就不是把数据发送到网络中!本质都是…...
【SQL】mysql常用命令
为方便查询,特整理MySQL常用命令。 约定:$后为Shell环境命令,>后为MySQL命令。 1 常用命令 第一步,连接数据库。 $ mysql -u root -p # 进入MySQL bin目录后执行,回车后输入密码连接。# 常用参数&…...
阿里云引领智算集群网络架构的新一轮变革
阿里云引领智算集群网络架构的新一轮变革 云布道师 11 月 8 日~ 10 日在江苏张家港召开的 CCF ChinaNet(即中国网络大会)上,众多院士、教授和业界技术领袖齐聚一堂,畅谈网络未来的发展方向,聚焦智算集群网络的创新变…...
几何合理的分片段感知的3D分子生成 FragGen - 评测
FragGen 来源于 2024 年 3 月 25 日 预印本的文章,文章题目是 Deep Geometry Handling and Fragment-wise Molecular 3D Graph Generation, 作者是 Odin Zhang,侯廷军,浙江大学药学院。FragGen 是一个基于分子片段的 3D 分子生成模…...
Python爬虫下载新闻,Flask展现新闻(2)
上篇讲了用Python从新闻网站上下载新闻,本篇讲用Flask展现新闻。关于Flask安装网上好多教程,不赘述。下面主要讲 HTML-Flask-数据 的关系。 简洁版 如图,页面简单,主要显示新闻标题。 分页,使用最简单的分页技术&…...
监控易监测对象及指标之:全面监控华为FusionInsight服务
随着大数据技术的广泛应用,华为FusionInsight以其卓越的性能和稳定性,成为了众多企业处理和分析海量数据的首选平台。然而,为了确保FusionInsight服务的持续稳定运行,对其进行全面监控至关重要。本文基于监控易工具,对…...
SQL面试题——蚂蚁SQL面试题 会话分组问题
会话分组问题 这里的分组不是简单的分组,而是会话的分组。 比如说,进入一个网站以后,可以连续的点击很多个页面,后台会记录用户的行为日志; 如果T日上午连续点击几个页面后退出了网站,直到第二天的下午才再次进入网站,单单从时间线上来看,昨天退出的那条日志跟今天进…...
nfs服务器--RHCE
一,简介 NFS(Network File System,网络文件系统)是FreeBSD支持的文件系统中的一种,它允许网络中的计 算机(不同的计算机、不同的操作系统)之间通过TCP/IP网络共享资源,主要在unix系…...
React--》如何高效管理前端环境变量:开发与生产环境配置详解
在前端开发中,如何让项目在不同环境下表现得更为灵活与高效,是每个开发者必须面对的挑战,从开发阶段的调试到生产环境的优化,环境变量配置无疑是其中的关键。 env配置文件:通常用于管理项目的环境变量,环境…...
Javascript高级—函数柯西化
函数柯西化(经典面试题) // 实现一个add方法,使计算结果能够满足如下预期: add(1)(2)(3) 6; add(1, 2, 3)(4) 10; add(1)(2)(3)(4)(5) 15;function add() {// 第一次执行时,定义一个数组专门用来存储所有的参数var…...
Sql进阶:字段中包含CSV,如何通过Sql解析CSV成多行多列?
Sql进阶 一、问题描述二、解决思路<一>、拆成多行<二>、拆成多列 三、代码实现 一、问题描述 Oracle数据库中某个字段value是CLOB类型,存的是csv格式的数据,如下所示 classnovalue1name,age,sex,… ‘李世民’,20,‘M’,…’ ‘李治’,18,‘M’,… ‘武则天’,16…...
linux之调度管理(5)-实时调度器
一、概述 在Linux内核中,实时进程总是比普通进程的优先级要高,实时进程的调度是由Real Time Scheduler(RT调度器)来管理,而普通进程由CFS调度器来管理。 实时进程支持的调度策略为:SCHED_FIFO和SCHED_RR。 SCHED_FIFOÿ…...
mybatis-plus: mapper-locations: “classpath*:/mapper/**/*.xml“配置!!!解释
和mybatis一样的道理!!!!如果不指定这个配置,通常要求 XML 映射文件和 Mapper 接口的包名和结构相同!!!! 如果没有配置 mapper-locations,通常文件结构应遵循…...
nacos-operator在k8s集群上部署nacos-server2.4.3版本踩坑实录
文章目录 操作步骤1. 拉取仓库代码2. 安装nacos-operator3. 安装nacos-server 坑点一坑点二nacos-ui页面访问同一集群环境下微服务连接nacos地址配置待办参考文档 操作步骤 1. 拉取仓库代码 (这一步主要用到代码中的相关yml文件,稍加修改用于部署容器&…...
面试篇-项目管理
⼀、构建管理 项目为什么选择Maven构建? 选择Maven进行项目构建有以下几个主要原因: 1. 依赖管理:Maven 提供了强大的依赖管理功能,可以自动下载项目所需的第三方库和依赖,并且可以管理这些依赖的版本、范围等信息。这简化了项…...
数仓建设之Oracle常见语法学习
1. 字符串截取 select substr(AAA-BBB, 1, instr(AAA-BBB, -, -1) - 1) 值 from dual; --AAA select substr(AAA-BBB, instr(AAA-BBB, -, -1) 1) 值 from dual; --BBB2. 帆软报表有参数SQL select a.agency_code, a.agency_name, a.agency_typefrom dw.dim_ta_subred_agency…...
物联网智能技术的深入探讨与案例分析
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
python语言基础-5 进阶语法-5.2 装饰器-5.2.2 简单装饰器
声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。 5.2.2 简单装饰器 装饰器的形式就是一个闭包,下面是一个简单的定义并使用…...
TransFormer--解码器:带掩码的多头注意力层
TransFormer--解码器:带掩码的多头注意力层 以英法翻译任务为例,假设训练数据集样本如下表所示。 原句目标翻译I am goodJe vais bienGood morningBonjourThank you very muchMerci beaucoup 上表所示的数据集由两部分组成:原句和目标句。在…...
【ArcGIS微课1000例】0130:图层组详解与使用
文章目录 一、图层组概述二、创建图层组三、在图层组中管理图层四、对话框中图层组的列表一、图层组概述 图层组包含其他图层。图层组有助于对地图中相关类型的图层进行组织,并且可用于定义高级绘制选项。例如,假设在地图上有两个图层分别用于表示铁路和高速公路。您可将这些…...
Linux中配置ntp服务
NTP:是Network Time Protocol的缩写又 称网络时间协议,是用来使计算机时间同步化的一种协议,用来同步网络中各主机的时 间,在linux系统中早期使用ntp来实现,后来使用chrony来实现。Chrony 应用本身已经有 几年了&#…...
微服务day10-Redis面试篇
Redis主从 搭建主从集群 建立集群时主节点会生成同一的replicationID,交给各个从节点。 集群中的缓冲区是一个环型数组,即若从节点宕机时间过长,可能导致命令被覆盖。 主从集群优化 哨兵原理 哨兵是一个集群来确保哨兵不出现问题。 服务状态监控 选举…...
STL序列式容器之list
相较于vector的连续性空间,list相对比较复杂;list内部使用了双向环形链表的方式对数据进行存储;list在增加元素时,采用了精准的方式分配一片空间对数据及附加指针等信息进行存储; list节点定义如下 template<clas…...
docker:基于Dockerfile镜像制作完整案例
目录 摘要目录结构介绍起始目录package目录target目录sh目录init.sh脚本start.sh脚本stop.sh脚本restart.sh脚本 config目录 步骤1、编写dockerfilescript.sh脚本 2、构件镜像查看镜像 3、保存镜像到本地服务器4、复制镜像文件到指定目录,并执行init.sh脚本5、查看挂…...
网站访客qq获取/在线视频用什么网址
摘要:华为导流测试平台通过对线上流量回放到被测环境中,利用线上真实流量进行充分测试,保证业务系统稳定上线。但是业务在导流测试过程中现网数据库往往难以同步到测试环境,导致现网数据无法正常回放,测试价值降低。由…...
网站缩略图存哪里好/电脑编程培训学校哪家好
好雪片片,不落别处 H.264有四种画质级别,分别是baseline, extended, main, high: 1、Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC; 2、Extended profil…...
简单的电商网站开发/凡科建站靠谱吗
Samba服务是现在Linux系统与Windows系统之间共享文件的最佳选择。 [rootstudy ~]# yum install samba -y #安装samba服务 [rootstudy ~]# cat -n /etc/samba/smb.conf #查看samba主配置文件 Samba服务程序中的参数以及作用 [global]参数作用 workgroup MYGROUP #工作组名…...
国内出版社网站建设/杭州小程序建设公司
2019独角兽企业重金招聘Python工程师标准>>> 1.13 单用户模式 1、重启服务器,在选择内核界面使用上下箭头移动 2、选择内核并按“e” 3、找到如下这行,加入 rw init/sysroot/bin/sh rw 表示读写. sysroot/bin/sh 原系统所在目录 启动加载程序 输入…...
做艺术品的网站/什么是百度竞价排名
2019独角兽企业重金招聘Python工程师标准>>> 基于《多台filebeatELK实践记录》做多台logstash的模拟 用了4台服务器33、34、48、49,结构如下:(不对的还望指正) 同理在48装logstash和filebeat,在49装filebea…...
怎么在百度做网站/杭州免费网站制作
原文转自Understanding Generative Adversarial Networks (GANs),将其翻译过来进行学习。1. 介绍Yann LeCun将生成对抗网络描述为“近十年来机器学习中最有趣的想法”。 的确,自从2014年由Ian J. Goodfellow及其合作者在文献Generative Adversarial Nets…...