排序算法之快速排序

【排序算法】快速排序原理及Java实现 快速排序是我们之前学习的冒泡排序的升级,他们都属于交换类排序,都是采用不断的比较和移动来实现排序的。快速排序是一种非常高效的排序算法,它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的记录从后面直接移动到前面,从而减少了总的比较次数和移动次数。同时采用“分而治之”的思想,把大的拆分为小的,小的拆分为更小的,其原理如下: 阅读详情

在讲解 快速排序 之前,我们提前引入了两个问题:

快速排序基石之荷兰国旗问题

快速排序基石之荷兰国旗问题II

如果你还未研读上面的两个题目,建议先研习一下,因为我们这章要讲解的快速排序原理就是基于上面两个问题的解决方式来做的

快速排序可以分为 3 个版本:

1.0 版本:荷兰国旗问题

固定选择最末元素为 num 值,保证 num 前的数组内容分为两部分

完成后 num 与 >num 区域的第一个元素交换,这样 num 确定好了位置

剩余就是递归新的两部分

代码部分:

int partition1(int *arr, int l, int r)
{	
	int less = l - 1;
	int more = r;
	
	while(l < more)
	{
		if(arr[l] <= arr[r])
		{
			swap(arr, ++less, l++);
		}
		else
		{
			l++;
		}
	}
	swap(arr, less+1, r);
	
	return less+1;
}

void doquickSort1(int *arr, int l, int r)
{
	if(l < r)
	{
		int pIdx = partition1(arr, l, r);

		doquickSort1(arr, l, pIdx-1);
		doquickSort1(arr, pIdx+1, r);
	}
}

2.0 版本:荷兰国旗问题II

固定选择最末元素为 num 值,保证 num 前的数组内容分为三部分

完成后 num 与 >num 区域的第一个元素交换,这样 num 确定好了位置一定在 == num 区域

剩余就是递归新的两部分

相比较 1.0 因为一次搞定了一批 == num 的数字,所以效率有提升

 

代码部分:

int* partition2(int *arr, int l, int r)
{	
	int less = l - 1;
	int more = r;
	
	while(l < more)
	{
		if(arr[l] < arr[r])
		{
			swap(arr, ++less, l++);
		}
		else if(arr[l] > arr[r])
		{
			swap(arr, --more, l);
		}
		else
		{
			l++;
		}
	}
	swap(arr, more, r);
	
	int *pIdx = (int *)malloc(sizeof(int) * 2);
	pIdx[0] = less+1;
	pIdx[1] = more;
	
	return pIdx;
}

void doquickSort2(int *arr, int l, int r)
{
	if(l < r)
	{
		int* pIdx = partition2(arr, l, r);    // 数组指代 == num 的区间坐标
		int newl = pIdx[0];
		int newr = pIdx[1];

		free(pIdx);
		doquickSort2(arr, l, newl-1);
		doquickSort2(arr, newr+1, r);
	}
}

3.0 版本:荷兰国旗问题II

面对1.0 或者 2.0 版本,面对最差情况,都是 O(N^2)

比如 1,2,3,4,5,6,7,8,9 (num 选定的很偏)

当然最好的情况就是选定的 num 在中间位置左右,这样左右的区间规模几乎相等

按照 master 公式(忘记的参考这里:时间复杂度之 Master 公式)

T(N) = 2 * T(N / 2) + O(N)   (左右规模都是 N /2,其余消耗在做partition过程)

这样计算出来的时间复杂度 = O(N* logN)

num 逐渐打偏就会退化成 O(N^2)的算法

采用范围内的随机选择一个数,当做num放到末尾

因为随机选的数,好情况与坏情况在概率上来讲都是一样的,每一个num造成的T(N)值都是等概率事件,都是 1 / N 的概率

把所有的数进行概率累加 + 数学上的长期期望得到时间复杂度 = O(N* logN)

数学的推理不在此讨论范围,记住就行

代码:

相对于2.0 版本仅有一个改动部分,就是不选用固定元素作为num

int randIdx = l + rand() % (r - l + 1);
swap(arr, randIdx, r); 
int* pIdx = partition2(arr, l, r);    // 依旧用 3 个区域

更多数据结构算法详解

七大排序算法之快速排序 七大排序算法之快速排序七大排序算法之快速排序 快速排序的介绍 快速排序的核心思想 简单例子 时间复杂度的讨论 每轮快排的具体实现 代码 快速排序的介绍:快速排序是C. A. R. Hoare在1962年提出的,平均时间复杂度为O(nlogn)级的高效率算法,也是目前O(nlogn)的排序算法中使用最多的算法,这段时间想把自己学过的算法都整理一遍,于是就写了这篇博客,来记录自己的学习过程吧…也希望能给 阅读详情

相关推荐

ADS笔记,新旧两组仿真数据进行绘图和列表对比

原理图器件参数的不同,怎么进行对比观看,操作如下。

彭辉荣的博客 3867

归并排序和快速排序-代码详解(Java)

左神的算法课 , 个人对于归并及快排的代码解析。

Al_lllllA的博客 479

使用Label Studio标注车牌数据:YOLOv26模型训练指南

在计算机视觉领域,数据标注是模型训练的基础环节,直接影响最终模型的识别精度。Label Studio作为专业的标注工具,支持多种标注类型和格式导出,特别适合目标检测任务的数据准备。通过多边形标注技术,可以精确捕捉车牌的四个角点,生成旋转矩形框(OBB)标注数据,这种标注方式相比传统水平框能更好地处理倾斜车牌场景。标注完成后,数据可导出为YOLO格式,直接用于YOLOv26等先进目标检测模型的训练。在实际工程中,合理的标注策略和严格的质量控制能显著提升车牌识别模型在复杂场景下的鲁棒性,适用于智能交通、停车场管

chuozhi7142的博客 902

算法初学(第二天)

1. 给定一个数组和一个数num,将比num小的数放在数组的左边,大的数放右边。 要求额外空间复杂度为O(1),时间复杂符为O(N) 即只借助有限个变量,只进行一次常数次操作 1.1 借助一个变量x,此变量指向数组的最前面-1,0~x表示小于等于num的范围 1.2 判断这个数比num大还是小,如果大的话保持不变,如果小的话,与索引为x+1的数进行交换 1.3...

ych_ych918的博客 354

DLMS—Cryptographic algorithms—(Green-Book)加密算法

密码学是数学的一个分支,基于数据的转换,并且可以用来提供多种安全服务:保密性、数据完整性、认证、授权和不可否认性。密码学依赖于两个基本组成部分:算法(或密码学方法)和密钥。算法是一个数学函数,而密钥是在转换过程中使用的参数。密码算法和密钥用于对数据应用密码保护(例如,加密数据或生成数字签名),以及移除或检查保护(例如,解密加密的数据或验证数字签名)。密码哈希函数:这类函数不需要密钥(尽管它们可以以使用密钥的模式使用)。哈希函数通常用作算法的一个组成部分,以提供安全服务。见9.2.3.2节。对称密钥算法。

一个bug是bug,多个bug能work 1706

Unity Shader Graph 2D - Procedural程序化图形转动的环状六边形

Hexagon又称六边形,在游戏中是十分常见的基础形状,本文将使用程序化的六边形来制作多个环状六边形叠加的转动动画效果,实践Unity Shader Graph中的常用节点功能。

Giver的博客 1928

快速排序三个版本(1.0,2.0,3.0)

快速排序 三个版本

qq_45599754的博客 629

快衰落、慢衰落,平坦衰落、频率选择性衰落

目录一、大尺度衰落和小尺度衰落二、平坦衰落和频率选择性衰落1.反射墙、固定天线模型2.相干带宽和时延扩展三、快衰落和慢衰落1.反射墙、运动天线模型2.相干时间和多普勒扩展四、联系总结 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、大尺度衰落和小尺度衰落 移动无线信道的主要特征是信道强度关于时间和频率的变化,大致分两种: 大尺度衰落: .

weixin_45662974的博客 3万+

快速排序(v 1.0)

快速排序法(quick sort)是目前所公认最快的排序方法之一,虽然快速排序法在最差状况下可以达O(n2),但是在多数的情况下,快速排序法的效率表现是相当不错的。 快速排序法的基本思想是在数组中找出适当的轴心,然后将数组一分为二,分别对左边与右边数组进行排序,而影响快速排序法效率的正是轴心的选择。 这边所介绍的第一个快速排序法版本,是在多数的教科书上所提及的版本,因为它最容易理解,也...

rush2012的专栏 201

STM32使用HAL库实现ModbusRTU主站核心要点

深入解析STM32如何利用HAL库高效实现ModbusRTU主站通信,重点讲解串口配置、定时控制与modbusrtu协议帧的构建方法,提升嵌入式通信稳定性与实时性。

weixin_42668301的博客 373

CloudCompare 二次开发(41)——点云重建三维凸包并计算体积

本文介绍了如何结合PCL与CloudCompare实现点云三维凸包的构建与可视化。通过代码集成,在CloudCompare界面添加功能按钮,实现点云数据转换、凸包构建、体积计算以及可视化显示。具体步骤包括:1) 在UI中添加功能按钮;2) 将点云数据转换为PCL格式;3) 使用PCL的ConvexHull算法构建三维凸包;4) 计算并显示凸包体积;5) 将结果以点云和网格形式可视化显示。最终实现了点云凸包的自动构建与体积计算功能,为点云处理提供了实用工具。

点云侠的博客 192

12.快速排序

**①问题1:**给定一个数组arr和一个数num,将小于等于num的数放在数组的左边大于num的数放在数组的右边(不要求有序)。要求额外空间复杂度为O(1),时间复杂度为O(N)。遍历数组元素,根据以下两种情况处理:【例】给定数组nums[3 5 6 7 4 3 8],给定一个数num【代码如下】 **②问题2:(荷兰国旗问题):**给定一个数组arr和一个数num,将小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度为O(1),时间复杂度为O(N

weixin_44897707的博客 263

Raspberry Pi 4 ARM Trusted Firmware 技术解析

摘要: 本文详细介绍了在树莓派4(Raspberry Pi 4)上移植ARM可信固件(TF-A)的实现方案与安全考量。该移植专注于BL31功能,作为非安全世界(如Linux内核)的启动桥梁,支持加载EL2级别程序。文章分析了启动流程、内存映射设计,并对比了RPi3与RPi4的关键差异,指出当前版本缺乏硬件级安全内存保护的局限性。此外,提供了构建指南、配置说明及设备树自动修补的实现细节,强调通过config.txt简单配置即可启动64位内核。该方案充分利用树莓派原有GPU固件流程,兼顾兼容性与简易性。

Linux内核架构师 932

经典排序算法之:快速排序

  快速排序可能是应用最广泛的排序算法。快速排序流行的原因是它实现简单、适用于各种不同的输入数据且在一般应用中比其他排序算法都要快很多。此次,我们来学习一下快速排序算法。 一、快速排序算法含义   快速排序是一种分治的排序算法。它会在数组中选择一个基准元素,讲数组分为两部分,使得第一部分中的所有元素都小于或等于基准元素,而第二部分中的所有元素都大于基准元素。对第一部分和第二部分递归的应用快速排序算法。 二、快速排序算法过程 例如:   对数组 [5 2 9 3 8 4 0 1 6 7 ]进行快速排序   

Ctra_aaa的博客 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

十大排序算法——快速排序

快速排序是对冒泡排序的一种改进。 快速排序原理 1.首先设定一个分界值,通过该分界值将数组分成左右两部分﹔ 2.将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边。此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值; 3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。 4.重复上述过程,可以看出,这是一个递归定义。通过递归将

龍弟-idea的博客 5181

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

双路快速排序和三路排序算法

三路快速排序是双路快速排序的进一步改进版本,三路排序算法把排序的数据分为三部分,分别为小于 v,等于 v,大于 v,v 为标定值,这样三部分的数据中,等于 v 的数据在下次递归中不再需要排序,小于 v 和大于 v 的数据也不会出现某一个特别多的情况),通过此方式三路快速排序算法的性能更优。如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对。我们可以使用本教程的归并思想求逆序对的数量。

b123321888的博客 1221

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java排序算法之快速排序

        快速排序,顾名思义,速度快;其时间复杂度为(NlogN),那么它是如何运作来实现高速排序的呢?先讲一下它的基本原理:         (1)寻找到一个枢纽元,也就是在一组元素中找一个元素(怎么找是有讲究的);         (2)然后在这组元素中,比这个枢纽元小的放在左边,比其大的放在右边;         (3)然后对左右重复上述两步,即可实现从小到大排序;      ...

boy_chen93的博客 1万+

排序算法——快速排序

排序算法 —— 快速排序 快速排序是现在使用的很多的一种排序算法,同时也是很有可能会被面试问到的一个基础排序算法题。 那么怎么了解快速排序呢? 其实想要了解快速排序,首先我们需要知道冒泡排序,这是为啥? 这是因为快速排序是在冒泡排序的基础上的改良呀! 冒泡排序 冒泡排序的基本思想:每次都比较相邻的两个元素,如果这两个元素大小位置不对劲,那就将这两个元素的位置交换一下,这样就会使得每次都有一个符合最...

小青的博客 278

快速排序算法详解与其他排序算法的比较

快速排序 属于原地排序,与自顶向下归并类似的是,也是先进行大数组的排序,然后递归到小数组,在进行排序时,先选定一个元素为切分元素,按大小将其他元素放到左右两侧即可 动画演示: P为切分元素 L为左标记 R为有标记 package Sort; import edu.princeton.cs.algs4.StdRandom; import static Sort.SortExample.*; import static edu.princeton.cs.algs4.StdRandom.unifo

qq_45921491的博客 1033

排序算法 -快速排序

排序算法-快快快速排序

shiyue 1234
上一篇: 快速排序基石之荷兰国旗问题II
下一篇: 2130. 链表最大孪生和
mrbone9
博客等级 码龄18年 1811粉丝 171原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值