数据结构-常见的七大排序
上节中我们学习了七大排序中的五种(插入排序、希尔排序、堆排序、选择排序、交换排序)
数据结构-常见的七大排序-CSDN博客
这节我们将要学习快速排序(hoare、指针法、挖洞法(快排的延伸)、快速排序非递归(栈))
1.快速排序
1.1 hoare法
1.1思路
1.选出一个key,一般是最左边或是最右边的。
2.定义一个begin和一个end,begin从左向右走,end从右向左走。(需要注意的是:若选择最左边的数据作为key,则需要end先走;若选择最右边的数据作为key,则需要bengin先走)。
3.在走的过程中,若end遇到小于key的数,则停下,begin开始走,直到begin遇到一个大于key的数时,将begin和right的内容交换,end再次开始走,如此进行下去,直到begin和end最终相遇,此时将相遇点的内容与key交换即可。(选取最左边的值作为key)
4.此时key的左边都是小于key的数,key的右边都是大于key的数
5.将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作,此时此部分已有序
1.2单趟动图如下:

1.3画图思路如下(单边)

代码如下:
//快速排序 hoare版本(左右指针法)
void QuickSort(int* arr, int begin, int end)
{//只有一个数或区间不存在if (begin >= end)return;int left = begin;int right = end;//选左边为keyint keyi = begin;while (begin < end){//右边选小 等号防止和key值相等 防止顺序begin和end越界while (arr[end] >= arr[keyi] && begin < end){--end;}//左边选大while (arr[begin] <= arr[keyi] && begin < end){++begin;}//小的换到右边,大的换到左边swap(&arr[begin], &arr[end]);}swap(&arr[keyi], &arr[end]);keyi = end;//[left,keyi-1]keyi[keyi+1,right]//无限向下分,直到一个数或为NULLQuickSort(arr, left, keyi - 1);QuickSort(arr,keyi + 1,right);
}
时间复杂度:
快速排序的过程类似于二叉树其高度为logN,每层约有N个数,如下图所示:

2.1前后指针法
2.1思路
1.选出一个key,一般是最左边或是最右边的。
2.起始时,prev指针指向序列开头,cur指针指向prev+1。
3.若cur指向的内容小于key,则prev先向后移动一位,然后交换prev和cur指针指向的内容,然后cur指针++;若cur指向的内容大于key,则cur指针直接++。如此进行下去,直到cur到达end位置,此时将key和++prev指针指向的内容交换即可。经过一次单趟排序,最终也能使得key左边的数据全部都小于key,key右边的数据全部都大于key。
然后也还是将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作
2.2单趟动图如下:

代码如下:
//快速排序法 前后指针版本
void QuickSort2(int* arr, int begin, int end)
{if (begin >= end)return;int cur = begin, prev = begin - 1;//前后指针int keyi = end;while (cur != keyi){if (arr[cur] < arr[keyi] && ++prev != cur){swap(&arr[cur], &arr[prev]);}++cur;}swap(&arr[++prev],&arr[keyi]);keyi = prev;//[begin,keyi -1]keyi[keyi+1,end]//与hoare类似,但又有不同QuickSort2(arr, begin, keyi - 1);QuickSort2(arr, keyi + 1, end);}
3.1挖洞法
3.1思路
挖坑法思路与hoare版本(左右指针法)思路类似
1.选出一个数据(一般是最左边或是最右边的)存放在key变量中,在该数据位置形成一个坑
2、还是定义一个L和一个R,L从左向右走,R从右向左走。(若在最左边挖坑,则需要R先走;若在最右边挖坑,则需要L先走)
3.2单趟动图如下:

代码如下:
//快速排序法 挖坑法
void QuickSort1(int* arr, int begin, int end)
{if (begin >= end)return;int left = begin,right = end;int key = arr[begin];//这里的key就为洞while (begin < end){//找小while (arr[end] >= key && begin < end){--end;}//小的放到左边的坑里arr[begin] = arr[end];//找大while (arr[begin] <= key && begin < end){++begin;}//大的放到右边的坑里arr[end] = arr[begin];}arr[begin] = key;int keyi = begin;//[left,keyi-1]keyi[keyi+1,right]QuickSort1(arr, left, keyi - 1);QuickSort1(arr, keyi + 1, right);
}
4.1快速排序非递归(栈)
与hoare快排类似,这里是利用栈的特点(先进后出,后进先出)
代码如下:
int PartSort2(int* a, int left, int right)
{// 三数取中,为了提高排序效率//这里可以省略int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);int keyi = left;int prev = left;int cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur)Swap(&a[prev], &a[cur]);cur++;}Swap(&a[prev], &a[keyi]);return prev;
}
void QuickSortNonHeap(int* a, int left, int right) {Stack st;StackInit(&st);StackPush(&st, right);StackPush(&st, left);while (!StackEmpty(&st) ){int begin = StackTop(&st);STpop(&st);int end = StackTop(&st);STpop(&st);int keyi = PartSort2(a, begin, end);if (keyi + 1 < end){StackPush(&st, end);StackPush(&st, keyi + 1);}if (begin < keyi - 1){StackPush(&st, keyi - 1);StackPush(&st, begin);}}StackDestroy(&st);
}
2.计数排序
2.1思路
计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤:1. 统计相同元素出现次数2. 根据统计的结果将序列回收到原来的序列中

代码如下:
void CountSort(int* a, int n) {int min = a[0], max = a[0];//找最小最大for (int i = 0; i < n; i++) {if (a[i] > max) {max = a[i];}if (a[i] < min) {min = a[i];}}int range = max - min + 1;//calloc开辟空间,存放值为0//malloc开辟空间,存放值为任意值;int* count = (int*)calloc(range, sizeof(int));if (count == NULL){perror("calloc fail");return;}//统计次数for (int i = 0; i < n; i++) {count[a[i] - min]++;}//排序int j = 0;for (int i = 0; i < range; i++) {while (count[i]--) {a[j++] = i + min;}}free(count);
}
1. 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。2. 时间复杂度:O(MAX(N,范围))3. 空间复杂度:O(范围)4. 稳定性:稳定
排序算法复杂度与稳定性
我们学习排序算法的目的是为了更快的效率,如下列举了基本算法的时间复杂度、空间复杂度,及稳定性

对于少量数据,可用冒泡排序、直接插入排序、简单排序排序,相对简单
对于大量数据,可用堆排序、快速排序归并排序,但要注意他们的使用条件
相关文章:
数据结构-常见的七大排序
上节中我们学习了七大排序中的五种(插入排序、希尔排序、堆排序、选择排序、交换排序) 数据结构-常见的七大排序-CSDN博客 这节我们将要学习快速排序(hoare、指针法、挖洞法(快排的延伸)、快速排序非递归(栈)) 1.快速排序 1.1 hoare法 1.1思路 1.选出一个key,一…...
离线安装部署springboot+vue系统到服务器
注意:首先服务器会有多个网卡,这些服务器的网卡连接所需要的文件可能不是我们默认的ifcfg-eth0/ifcfgens33,可以试着切换一下服务器网线插入的接口,要保证服务器网线插入的接口和网卡对应的文件一致 说明,在一些政府(保…...
【STM32】ADC模拟数字转换(规则组单通道)
本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 目录 ADC简介 ADC时钟配置 引脚模拟输入模式 规则组通道选择 ADC初始化 工作模式 数据对齐 触发转换方式 连续与单次转换模式 扫描模式 组内的通道个数 ADC初始化框架 ADC上电 ADC校…...
WPF 数据模板DataTemplate、控件模板ControlTemplate、Style、ItemsPreseter
一言蔽之,Template就是“外衣”—— ControlTemplate是控件的外衣, DataTemplate是数据的外衣。 DataTemplate 它定义了一个数据对象的可视化结构 DataTemplate常用的地方有3处,分别是: ContentControl的ContentTemplate属性&…...
Windows下搭建Telegraf+Influxdb+Grafana(详解一)
InfluxDB(时序数据库),常用使用场景:监控数据统计。 grafana,用作监控页面的前端展示。 telegraf,数据采集器。 所有的安装包都上传到网盘 链接: https://pan.baidu.com/s/1Lv6UnfueK7URx7emAatoYg 提取…...
同城搭子社交系统开发同城搭子群活动APP圈子动态小程序
引言 随着互联网技术的飞速发展,同城搭子社交系统作为一种新兴的社交模式,正逐渐在市场中占据一席之地。该系统通过搭子群活动和圈子动态等功能,为用户提供了一种高效、精准的社交体验。本文将从市场前景、使用人群、盈利模式以及运营推广等…...
大厂最佳实践 | Stripe 如何防止重复付款
为什么扣了我两笔钱? 2010年,美国加利福尼亚州的两兄弟打算创办一家公司,但他们发现建立网上支付十分困难。于是,他们决定开发一款在线支付服务,并将其命名为Stripe。 随着用户数量的不断增长,重复付费问题…...
Raspberry Pi Pico 2 上实现:实时机器学习(ML)音频噪音抑制功能
Arm 公司的首席软件工程师 Sandeep Mistry 为我们展示了一种全新的巧妙方法: 在 Raspberry Pi Pico 2 上如何将音频噪音抑制应用于麦克风输入。 机器学习(ML)技术彻底改变了许多软件应用程序的开发方式。应用程序开发人员现在可以为所需系统整…...
安全自动化和编排:如何使用自动化工具和编排技术来提高安全操作效率。(第二篇)
深入理解Kubernetes环境中的安全自动化与编排(第二篇) 1. 引言 Kubernetes作为现代容器编排平台的主流选择,正在被越来越多的企业用于部署和管理其容器化应用。在Kubernetes环境中实施安全自动化与编排,既能够提升系统的安全性&…...
HarmonyOS WebView
HarmonyOS WebView Web组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、html格式文本数据。Web组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,C…...
解决elementUI表格里嵌套输入框,检验时错误信息被遮挡
1.表格 自定义错误信息显示div <el-form-item label"租赁价格" prop"supplierId"><el-table-column prop"salePrice" label"销售价" align"center"><template slot-scope"scope"><el-form-…...
Unity读取Android外部文件
最近近到个小需求,需要读Android件夹中的图片.在这里做一个记录. 首先读写部分,这里以图片为例子: 一读写部分 写入部分: 需要注意的是因为只有这个地址支持外部读写,所以这里用到的地址都以 :Application.persistentDataPath为地址起始. private Texture2D __CaptureCamera…...
【5.3 python中的元组】
5.3 python中的元组 Python中的元组(Tuple)是一种用于存储多个项目(可以是不同类型)的序列数据结构,但它与列表(List)不同,主要区别在于元组是不可变的(immutable&#…...
Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null
Debezium报错处理系列之第116篇:Caused by: java.lang.NumberFormatException: null 一、完整报错二、错误原因三、解决方法Debezium从入门到精通系列之:研究Debezium技术遇到的各种错误解决方法汇总: Debezium从入门到精通系列之:百篇系列文章汇总之研究Debezium技术遇到的…...
【启明智显技术分享】工业级HMI芯片Model3C/Model3A开发过程中问题记录笔记二
一、Model3C/Model3A芯片介绍 Model3C/Model3A是启明智显针对工业、行业以及车载产品市场推出的一款高性能、低成本的工业级HMI(Human-Machine Interface,人机界面)芯片。两颗芯片硬件PIN TO PIN;区别在于内置的PSRAM大小不同。该…...
Python 函数返回yield还是return?这是个问题
如果你刚入门 Python,你可能之前没有遇到过yield。虽然它看起来很奇怪,但它是你编码工具库中的一个重要工具。在成为 Python 大师的道路上,你必须掌握它。 返回列表的函数 假设有一个函数,它可以一次性生成一系列值,…...
Linux系统性能调优
Linux系统性能调优是一个复杂而细致的过程,涉及硬件、软件、内核参数、进程管理等多个方面。以下将从多个角度详细介绍Linux系统性能调优的技巧,旨在帮助用户提升系统的运行效率和稳定性。 一、硬件层面的调优 内存升级: 增加物理内存可以减…...
PHPStorm 环境配置与应用详解
大家好,我是程序员小羊! 前言: PHPStorm 是 JetBrains 出品的一款专业 PHP 集成开发环境(IDE),凭借其智能的代码补全、调试功能、深度框架支持和前端开发工具,为用户提供了丰富的功能和工具…...
前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载
前端各种文本文件预览 文本编辑excel预览编辑 pdf预览word预览 excel下载pdf下载word下载 各种文本文件预览(pdf, xlsx, docx, cpp, java, sql, py, vue, html, js, json, css, xml, rust, md, txt, log, fa, fasta, tsv, csv 等各种文本文件) 其中 除p…...
【Qt】QPluginLoader 类学习
文章目录 一、简介二、常用方法2.1 构造函数2.2 动态加载方法——load()2.3 检查是否加载成功——isLoaded()2.4 访问插件中的根组件——instance()2.5 卸载插件——unload() 一、简介 QPluginLoader 类在运行时加载插件。 QPluginLoader 提供对Qt插件的访问。Qt插件存储在共享…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
