【数据结构】快排之三路划分

目录

一、前言

二、 快排性能的关键点分析

三、 三路划分基本思想

四、 思路分析

五、提醒

六、代码实现


一、前言

继续对快速排序的深入优化进行探讨

二、 快排性能的关键点分析

决定快排性能的关键点是每次单趟排序后,key对数组的分割。

如果每次选key都能做到基本二分居中,那么快排的递归树就是棵均匀的满二叉树,性能最佳。虽然实践中不能做到每次都二分居中,但是性能也还是可控的。

但如果每次选到最大值/最小值,划分0个和n-1的子问题时,时间复杂度就为O(N^2),当数组序列有序时就会出现这样的问题。前面已经用三数取中or随机选key解决了该问题。

但是,有些场景下hoae和lomuto(前后指针法)还是适应的不是很好,就是当数组中有大量重复数据时,该场景下性能是有些退化的。

针对数组中有大量重复数据的问题,我们采用三路划分的方式来解决。

三、 三路划分基本思想

那什么是三路划分呢?

在之前快排是排完序把key放在中间,左边比key值小,右边比key大,跟key相等的值在哪里并没有规定,跟key相等的值可以在左边,也可以在右边。

三路划分的基本思想是将数组分为三个部分:

当面对有大量跟key相同的值时,三路划分的核心思想类似hoare的左右指针和lomuto的前后指针的结合。核心思想是把数组中的数据分为三段:

小于基准元素key的放在左边

等于基准元素key的全部放在中间

大于基准元素key的放在右边

所以叫做三路划分算法。

通过三路划分的方式,可以避免在数组中有大量重复元素时出现的性能问题。

四、 思路分析

基本思路如下:

这里跟lomuto的前后指针法相结合(排升序)

  • key默认取left位置的值
  • left指向区间第一个元素位置,right指向区间最后一个元素位置,cur指向left+1的位置
  • 对cur进行判断
  1. 如果cur<key,cur指向的值与left位置的值进行交换,然后left++,cur++
  2. 如果cur>key,cur指向的值与right位置的值进行交换,然后right--
  3. 如果cur==key,cur++
  • 直到cur>right结束,排完单趟

结合图进行分析:

五、提醒

为什么cur==right要继续呢?

因为假如cur没有遇见比key大的值,right没有--,那么cur与right在相同位置时,并不能确定right所指向的值是否小于key。

例如下图的情况:

六、代码实现

//交换算法
void swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}//三数取中
int GetMidi(int* a, int left, int right)
{int midi = (left + right) / 2;if (a[left] > a[right]){if (a[left] < a[midi]){return left;}else if (a[midi] < a[right]){return right;}else{return midi;}}else{if (a[right] < a[midi]){return right;}else if (a[midi] < a[left]){return left;}else{return midi;}}
}//三路划分算法
void QuickSort_Three_Way_Partition(int* a, int left, int right) //参数为数组下标
{if (left >= right){return;}int midi = GetMidi(a, left, right);swap(&a[left], &a[midi]);int begin = left;int end = right;int key = a[left];int cur = left + 1;while (cur <= end){if (a[cur] < key){swap(&a[cur], &a[begin]);begin++;cur++;}else if (a[cur] > key){swap(&a[cur], &a[end]);end--;}else if (a[cur] == key){cur++;}}		//递归左右区间QuickSort_Three_Way_Partition(a, left,begin-1);QuickSort_Three_Way_Partition(a, end+1, right);
}int main()
{int arr[] = {7,13,6,2,7,7,23,7,7,98,11,6,9,1,66,21,5};int sz = sizeof(arr) / sizeof(arr[0]);QuickSort_Three_Way_Partition(arr,0,sz-1);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka面试题解答(一)

1.kafka消息发送的流程&#xff1f; 生产者&#xff1a;在消息发送的过程中涉及到了两个线程&#xff1a;main线程和sender线程。在main线程中创建了一个双端队列RecordAccumulator&#xff08;默认32m&#xff09;。main线程将消息发送RecordAccumulator,sender线程不断地从R…

如何使用 XML Schema

如何使用 XML Schema XML Schema,也称为XSD(XML Schema Definition),是一种用于定义XML文档结构和内容的语言。它提供了一种强大的方式来描述XML文档中允许的元素、属性和数据类型。使用XML Schema,可以确保XML文档符合预定义的结构,这对于数据交换、数据验证和应用程序…

基于yolov8、yolov5的番茄成熟度检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;番茄成熟度检测在农业生产及质量控制中起着至关重要的作用&#xff0c;不仅能帮助农民及时采摘成熟的番茄&#xff0c;还为自动化农业监测提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的番茄成熟度检测模型&#xff0c;该模型使用了…

Oracle 数据库创建导入

注意&#xff1a;本教程中的有些命令您可能并不熟悉&#xff0c;但没关系&#xff0c;只需按照说明一步一步创建示例数据库即可。在之后的教程中&#xff0c;会详细介绍每个命令。 1.创建新用户并授予权限 1.1.打开 首先&#xff0c;启动 SQL plus 程序的命令行&#xff1a;…

[数组二分查找] 0081. 搜索旋转排序数组||

文章目录 1. 题目链接2. 题目大意3. 示例4. 解题思路5. 参考代码 1. 题目链接 81. 搜索旋转排序数组 II - 力扣&#xff08;LeetCode&#xff09; 2. 题目大意 描述&#xff1a;一个按照升序排列的整数数组 nums&#xff0c;在位置的某个下标 k 处进行了旋转操作。 &#xff…

为centos7分配ip

前提&#xff1a; 安装好centos7 编辑文件 进入编辑模式[dmdbalocalhost ~]$ vim /etc/sysconfig/network-scripts/ifcfg-ens33 修改 BOOTPROTOstatic DNBOOTyes IPADDR192.168.152.11 NETMASK255.255.255.0 GATEWAY192.168.152.2 DNS18.8.8.8 点击esc .输入“:wq” 保存退…

【Unity/QFramework】QFramework学习笔记

文章目录 基础流程示例程序【PointGame】ArchitectureStoragePlayerPrefsStorage : IStorage ModelGameModel : AbstractModel, IGameModel ControllerGame : MonoBehaviour, IControllerEnemy : MonoBehaviour, IControllerMissArea : MonoBehaviour, IController CommandStar…

内网安全-代理技术-socket协议

小迪安全网络架构图&#xff1a; 背景&#xff1a;当前获取window7 出网主机的shell。 1.使用msf上线&#xff0c;查看路由 run autoroute -p 添加路由&#xff1a; run post/multi/manage/autoroute 使用socks模块开启节点&#xff0c;作为流量跳板 msf6 exploit(multi/ha…

GaussDB部署架构

GaussDB部署架构 云数据库GaussDB管理平台&#xff08;TPOPS&#xff09;基于B/S架构开发&#xff0c;由Web、管控Service、管控Agent三部分组成&#xff0c;软件结构如图1所示。 图1 各节点部署架构 Web&#xff1a;作为用户接入子系统&#xff0c;用于将用户在Web下发的操作…

如何使用.bat实现电脑自动重启?

1、在电脑桌面新建一个记事本文档&#xff0c;将如下内容写进去&#xff1a; echo off shutdown /r /t 02、然后&#xff0c;保存一下&#xff0c;再把桌面此文件重命名为电脑重启.bat 3、双击此程序&#xff0c;可以立刻重启电脑。 PS&#xff1a;① 此程序会不保存任何当前…

YOLOv11融合CVPR[2024]自适应扩张卷积FADC模块及相关改进思路|YOLO改进最简教程

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Frequency-Adaptive Dilated Convolution for Semantic Segmentation》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2403.05369 代码…

简单叙述 Spring Boot 启动过程

文章目录 1. 准备阶段&#xff1a;应用启动的入口2. 创建 SpringApplication 对象&#xff1a;开始启动工作3. 配置环境&#xff08;Environment&#xff09;&#xff1a;识别开发环境与生产环境4. 启动监听器和初始化器&#xff1a;感知启动的关键事件5. 创建 ApplicationCont…

[算法初阶]埃氏筛法与欧拉筛

素数的定义&#xff1a; 首先我们明白&#xff1a;素数的定义是只能整除1和本身&#xff08;1不是素数&#xff09;。 我们判断一个数n是不是素数时&#xff0c;可以采用试除法&#xff0c;即从i2开始&#xff0c;一直让n去%i&#xff0c;直到i*i<n c语言: #include<…

Python 数据文件读写教程

Python 数据文件读写教程 在数据科学和软件开发中&#xff0c;文件的读写操作是至关重要的。Python 作为一门功能强大的编程语言&#xff0c;提供了多种方式来处理文件&#xff0c;包括文本文件、CSV 文件、JSON 文件等。在本教程中&#xff0c;我们将深入探讨 Python 中的数据…

CSS多列布局:打破传统布局的束缚

你是否曾为如何让页面中的文字内容更加美观、易读而烦恼&#xff1f;传统的单列布局虽然简单&#xff0c;但有时并不能满足我们对页面布局的多样化需求。别担心&#xff0c;CSS 多列布局能轻松帮你解决这个问题&#xff01; 一、什么是 CSS 多列布局&#xff1f; 多列布局&am…

在uniapp当中隐藏掉默认tabbar并且使用自己的tabbar

1. 修改配置 "tabBar": {"custom": true,"selectedColor": "#ffdead","list": [{"pagePath": "pages/index/index","text": "首页"}] },//在引入自定义Tabbar组件的时候在载入的时…

新手小白学习docker第九弹-----高级篇start-Dockerfile

docker目录 1 Dockerfile是什么2 Dockerfile能干嘛3 如何书写Dockerfile3.1 Dockerfile构建过程解析3.2 小总结3.3 Dockerfile的基本知识3.5 保留字FROMMAINTAINERRUN 有两种方式EXPOSEWORKDIRENVUSERVOLUMEADDCMDENTRYPOINT 4 后记 1 Dockerfile是什么 Dockerfile顾名思义就是…

模拟实现优先级队列

目录 定义 特点 构造函数 常用方法 关于扩容的问题 关于建堆的问题 向上调整和向下调整的比较 &#xff08;向上调整&#xff09;代码 &#xff08;向下调整&#xff09;代码 关于入队列和出队列问题 模拟实现优先级队列代码 关于堆排序的问题 堆排序代码 关于对…

Autosar CP DDS规范导读

Autosar CP DDS 主要用途 数据通信 中间件协议&#xff1a;作为一种中间件协议&#xff0c;DDS实现了应用程序之间的高效数据通信&#xff0c;能够在不同的软件组件和ECU之间传输数据&#xff0c;确保数据的实时性和可靠性。跨平台通信&#xff1a;支持在AUTOSAR CP平台上的不同…

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)

数字IC实践项目&#xff08;10&#xff09;—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证&#xff08;付费项目&#xff09; 前言项目框图1&#xff09;DDR4 Verification IP2&#xff09;DDR4 JEDEC Model & Tb 项目文件1&#xff09;DDR4 Veri…