数组快排的四种方法

算法入门4-快速排序 快速排序本质是寻找基准值在数组中索引的过程。 实际操作是选取一个基准值,遍历数组,将小于基准值的数放到数组左边,等于基准值的数放到数组中间,大于基准值的数放到数组右边,那么,中间等于区域就是基准值的索引位置,也就是基准值已经排好序。然后小于区域继续选取自己的基准值,大于区域继续选取自己的基准值,继续根据基准值划分区域,递归这个过程,直到整个数组有序。 阅读详情

 1.快排递归版

如上图所示

数组第一个数值为key,设立两个指针L和R从数组两边向中间移动,右边指针先移动,如果右边指针指向比key小的数值那么key继续向中间移动,直到指向的数值比key要大停止。左边指针在右边指针停止后移动,如果指向了比key数值小的那么继续向中间移动,直到指向比key要大或者与R指针指向的位置相同停下。

再左边指针停下后如果L指针和R指针没有重合那么交换L和R指向位置的数据,如果L指针和R指针重合那么交换key和R或L指针指向的数据。这样在key左边的数据就比key小在key右边的数据就比key要大。我们再来看图理解 

通过不断的递归最终达到排序的目的,使每个数都放在自己大小对应的位置。

重点:在递归只剩一个数或没有数的时候return

代码实现如下

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
void QuickSort(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	if (right - left < 10)
	{
		InsertSort(a, right-left);
		return;
	}
	int mid = Getmid(a, left, right);
	swap(&a[left], &a[mid]);
	int key1 = left;
	int begin = left + 1, end = right;
	while (begin < end)
	{
		while (a[end] > a[key1] && begin != end)
		{
			end--;
		}
		while (a[begin] < a[key1]&& begin!=end)
		{
			begin++;
		}
		swap(&a[begin], &a[end]);
		if (begin == end)
		{
			swap(&a[key1], &a[end]);
		}
	}

	QuickSort(a, end + 1, right);
	QuickSort(a, left, end - 1);

}

2.快排非递归

快排非递归和递归相似,主要是要考虑如何存放数据(函数处理时左右的位置数据)

我们可以设置一个栈来存储数据left 和 right

每次排完序将两边的左右位置数据放入栈中,下一次排序在将栈中的数据拿出来用,用完再将两边的数据放入栈中,当两边其中有一边的数据个数只有一个或者是一个数据都没有,那么就不需要将左右两边的位置数据放入栈中。当栈中没有数据时停止循环,排序结束。

代码实现如下

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
int PartSort1(int* a, int left, int right)
{
	int MID = Getmid(a, left, right);
	swap(&a[left], &a[MID]);
	int begin = left;
	int keyi = left;
	int end = right;
	while (begin<end)
	{
		while (a[keyi] <= a[end] &&  begin < end)
		{
			end--;
		}
		while (a[keyi] >= a[begin] && begin < end)
		{
			begin++;
		}
		swap(&a[begin], &a[end]);
	}
	swap(&a[keyi], &a[begin]);
	return begin;
}
void QuickSortNonR(int* a, int left, int right)
{
	ST SQ;
	STInit(&SQ);
	int begin = left;
	int end = right;
	STPush(&SQ, begin);
	STPush(&SQ, end);
	while (!STEmpty(&SQ))
	{
		end = STTop(&SQ);
		STPop(&SQ);
		begin = STTop(&SQ);
		STPop(&SQ);
		int keyi = PartSort1(a, begin, end);
		if (keyi - 1> begin)
		{
			STPush(&SQ, begin);
			STPush(&SQ, keyi - 1);
		}
		if (keyi + 1 < end)
		{
			STPush(&SQ, keyi + 1);
			STPush(&SQ, end);
		}
	}
}

3.快排前后指针法

快排前后指针依然是设立数组第一个数为key,然后设立两个指针front和back,front指向key的下一个位置,back指向key,排序时back向前走一步,然后front再向前走一步,如果front指向的值比key要大那么front继续向前走一步,如果front指向的值要比key要小那么back向前走一步,并且back指向的值与front进行交换,直到front指向的位置超出数组停止循环,key指向的数值与back进行交换,完成一次排序。

具体流程请看VCR

代码实现如下 

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
int PartSort3(int* a, int left, int right)
{
	int head = left+1, tail = left;
	while (head <= right&& head>tail)
	{
		if (a[head] >= a[left])
		{
			head++;
		}
		else
		{
			tail++;
			swap(&a[tail], &a[head]);
		}
	}
	swap(&a[tail], &a[left]);
	return tail;
}

4.快排挖坑法 

设立一个整形变量key存储数组第一个数,将数组第一个数置为0(不置也没关系)

再设立两个指针一个L指向数组第二个节点,一个R指向数组最后一个节点,从R开始,向中间遍历直到遇到比key小的数停下,然后L指针开始从数组左边向中间遍历直到遇到比key大的数据停下,当L停下后将R指向的数据放入空的位置中将L的数据放入R中,然后继续这样的循环直到L遇上了R,那么他们指向的数据放入空的位置中再将key的数据放入L中便完成了一次排序

代码实现如下

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
int PartSort2(int* a, int left, int right)
{
	int MID = Getmid(a, left, right);
	swap(&a[left], &a[MID]);
	int begin = left;
	int keyi = left;
	int num = a[left];
	int end = right;
	while (begin < end)
	{
		while (num <= a[end] && begin < end)
		{
			end--;
		}
		swap(&a[keyi], &a[end]);
		keyi = end;
		while (num >= a[begin] && begin < end)
		{
			begin++;
		}
		swap(&a[begin], &a[keyi]);
		keyi = begin;
	}
	a[keyi] = num;
	return begin;
}

快速排序(快排) (C语言实现) 本篇博客学习内容是快速排序,快速排序有多种不同的版本和优化,我们这次的目的就是将这些版本都搞明白,废话不多说,我们开始。 阅读详情

相关推荐

【LPDDR4 - 学习二】LPDDR4 介绍 ——LPDDR4 芯片引脚说明解析

本文系统解析了LPDDR4内存芯片的引脚定义与特性,重点介绍了272球POPFBGA封装的双通道架构。内容涵盖电源管理(三级供电架构与上电时序)、控制信号(差分时钟与复用命令总线)、数据接口(16位双向数据总线与选通信号)以及校准复位等核心模块。通过表格详细列明了各引脚电压范围、功能定义及工程注意事项,并附有典型封装球位分布图。全文基于JEDEC标准,为移动设备内存设计提供全面的硬件参考,特别强调电源时序控制、信号完整性及抗干扰设计等关键点。

zap15622077817的博客 2649

数组排序——快速排序

数组排序——快速排序1、数组排序之快速排序    一趟快速排序的算法是:          1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;         2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];        3)从j开始向前搜索,即由后开始向前搜索(j=j-1即j--),找到第一个小于key的值A[j],A[i]与A[j]交换;        4)从...

风暴计划 5625

mfcc总结,这个mel三角滤波器分组到底是如何起作用的呢?

先看fft频谱图(这是4096字节取样fft计算,横轴频率是从0到512,后边意义不大,未取,纵轴是振幅),那些我随便画的蓝色线,你有什么联想?: 再看,这绿色线,是否有一种上升后,便逐渐式微的感觉,都是三角形的,这或许也是mel当初和绝大多数人看到的: 如果在振幅上加上一条限制的黑线(振幅门槛限制),黑色线以下很多频率就没有意义了,你看,有用的频率连一半(512/2=256)都占不到...

ganggangwawa的博客 9910

排序算法 - 快速排序(4种方法实现)

本文介绍了快速排序算法的挖坑法,前后指针法,左右指针法,非递归实现,以及使排序算法效率提高的三数取中

originalHSL的博客 1万+

BES2810_best1702_best1702_ibrt_三者关系深度解析

一颗芯片的三个名字:BES2810、best1702 与 best1702_ibrt 关系深度解析

weixin_42162924的博客 350

TPAMI 2024 | 重新思考多焦点图像融合中客观评价指标的有效性:一种基于统计的方法

作为一种延长光学镜头景深(DOF)的有效技术,多焦点图像融合最近成为图像处理社区的一个活跃话题。然而,该领域仍然存在一个未解决的主要问题,即缺乏选择客观评价指标的通用标准。因此,不同研究中使用的指标往往差异显著,导致难以实现公正的评估。为了解决这个问题,本文提出了一种基于统计的方法来验证多焦点图像融合中客观指标的有效性。核心思想是采用统计相关性度量来评估某个融合指标与一些流行的全参考图像质量评估模型之间的性能一致性。

小白学视觉 329

最快的排序方法-----快速排序

一,快速排序的思想 1,在一个无序的数组里随机找一个作为基准值。 2,然后让数组里的每一个数字和基准值比较,比基准值大的放在基准值右边,比基准值小的,放在基准值左边。 3,递归调用这个函数,使得整个数组有序。 二,快速排序的实现方法 方法一:交换法 取最后一个数据为基准值,begin标记数组第一个数据,end标记数组最后一个数据 begin++向后走,找到比基准值大的数停下来,end–向前走,找...

wfc1998的博客 2万+

基于 STM32 设计的 HC05 蓝牙音箱

本项目介绍如何使用 STM32 微控制器和 HC05 蓝牙模块设计一个简单的蓝牙音箱。该音箱可以接收来自手机或其他蓝牙设备的音频数据,并通过扬声器播放。该项目展示了如何使用 STM32 微控制器和 HC05 蓝牙模块设计一个简单的蓝牙音箱。易于实现功能实用可扩展性强如果您需要开发一个蓝牙音箱,该项目可以作为参考。

走向CTO的路上... 2473

js中的四种常用数组排序方法(冒泡、选择、插入、快排)及sort排序

1.冒泡排序 原理: 比较两个相邻的元素,如果第一个比第二个大,就交换他们的位置 对所有的元素重复以上步骤,直至排序完成 var arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; document.body.innerHTML += `排序前:${arr}<br /><hr>`; function arraySort(arr){ for(var i=0;i<arr.length;i++){ for(var j=0;j&

AK的博客 6056

风电功率预测项目技术白皮书:短期、超短期、中长期全尺度算法详解与工程落地

聚焦风电功率预测的时间尺度与算法:短期(0~72h)以XGBoost/LightGBM/CatBoost及深度学习为主,超短期(0~4h)采用ARMA+LSTM,中长期用LightGBM等,并涵盖概率预测、多气象源融合、AI大模型+物理模型混合策略、极端天气应对及工程运维要点。

算法工程师 329

用 OP-TEE 给 AI 模型“上锁”:密文存储、TEE 解密放行、推理后销毁(实战可落地)

本文提出一种基于OP-TEE的AI模型保护方案,通过两级密钥体系确保模型静态存储为密文,运行时仅在TEE内解密。方案采用KEK+DEK架构,DEK永不出TEE,支持分块解密与可验证擦除。该方案能有效防御静态分析、应用层逆向等威胁,但需承认其物理级攻击的局限性。文章详细描述了端到端架构、文件格式设计及TA实现要点,包括密钥管理、分块解密策略和销毁机制,为设备侧AI部署提供了工程可行的安全解决方案。

Interview_TC的博客 291

常用排序方法、sort的实现原理、快排的优化

常用排序方法、sort的实现原理、快排的优化

qq_43178432的博客 1295

第3版•系统集成项目管理工程师(中级) │ 告别迷茫!案例分析高分攻略

🥏第3版•系统集成项目管理工程师(中级) │ 告别迷茫!案例分析高分攻略

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 3871

详解快排的四种方式

快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。

jingfeng514的博客 1151

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

《算法导论》第7章 快速排序 (四种变形)

这一章的正文及思考题部分讲到了快速排序及其几种变形,包括:Hoare快排, 普通快排,随机快排,三数取中快排。 这些快排的区别主要是划分方法PARTITION算法的不同:如何选取主元,划分出的 两部分范围是什么。根据划分出的范围不同,各变形的QUICKSORT有微小的差别。 1. Hoare快排 Hoare划分是最初的版本,与《算法导论》中的划分版本相比,它选取第...

系统运维 136

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

常见题:无序数组中第k大的数(python)

思路一:暴力解法 先对数组排序,然后找出第k个位置 sorted(nums)[-k] 算法的时间复杂度为 O(N log N),空间复杂度为 O(1) 思路二:利用快排思想 (https://blog.youkuaiyun.com/wenqiwenqi123/article/details/81669899) 快速排序每次把一个元素交换到正确的位置,同时把左边的都放上大的,右边都放上小的。这个算法每一次选取...

扣扣biubiubiu~ 3795

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

剑指offer#39.数组中次数超过一般的数字

[题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。](https://www.nowcoder.com/questionTerminal/e8a1b01a2df14cb2b228b30ee6a92163?f=discussion...

weixin_37549298的博客 158

[剑指offer]-数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 分析: 如果将这个数组排序,那么中位数一定是要求得这数; 思路: 方法一:用sort先排序,然后中间数即为所求;时间复杂度O(nlogn) 方法二:采用用户“分形叶”...

yuemingyang7010的博客 170

第K大元素方法

问题:在长度为N的乱序数组中寻找第k(n>=k)大的元素。 (1)最简单直接:先排序再找 最简单直接的想法是首先进行排序。假设元素的数量不大,比如才几千个,那就可以先进行排序,比如用快排或堆排,平均时间复杂度为O(N*logN),然后取出前k个,于是总时间复杂度为O(NlogN)+O(k)=O(NlogN)。当然这种做法是浪费了不少的时间的,因为题目只要求找出第k大的元素,而不需要数据是有序的。 (2)部分元素排序:k次冒泡 当k比较小的时候,k趟排序是个比较不错的方法。我们只需要排序最大的k个元素即

weixin_43887870的博客 690

LeetCode 215. 数组中的第K个最大元素

题目 在未排序的数组中找到第k个最大的元素。请注意,它是数组有序排列后的第k个最大元素,而不是第k个不同元素。 例如, 给出[3,2,1,5,6,4]和k = 2,返回5。 注意事项: 你可以假设k总是有效的,1 ≤ k ≤数组的长度。 方法一: 先对数组快速排序再选择第K大的。时间复杂度O(nlgn) 空间复杂度O(1) 方法二: 维持一个大小...

Mr.hu 365

数组中出现次数超过一半的数字

题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 思路 方法一 排序,使用sort进行排序。如果数组中存在出现次数超过数组一半的,那么它只可能是中位数。扫描统计中位数出现次数,超过一半则返回。 时间复杂度:O(nlog...

m0_37965348的博客 175

剑指 Offer最小的k个数

题目描述 输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 示例 1: 输入:arr = [3,2,1], k = 2 输出:[1,2] 或者 [2,1] 示例 2: 输入:arr = [0,1,2,1], k = 1 输出:[0] 排序 class Solution { public int[] getLeastNumbers(int[] arr, int k) { int[] vec = n

一个白馒头的博客 109

查找数组中出现次数超过一半的数

查找数组中出现次数超过一半的数 解法一 对数组运用快排,取 n/2处的数为超过一半的数 解法二 用空间换时间,以散列表中存储出现过的数据,和出现的次数 解法三 每次 删除数组中两个不同的数,剩下的那个数就是出现次数超过一半的数 解法四 保存两个值 ,candidate用来保存数组中遍历的某个数,nTimes 用来保存遍历到的数出现的次数 int findOneNumber(int *a,int n...

保持热爱,持续学习 386

递归、非递归、单向、单链表——快排

快速排序 非递归快排 import java.util.Arrays; import java.util.Stack; public class QuickSort { public static int[] sort(int[] arr){ Stack<Integer> stack = new Stack<>(); //左边界 stack.push(0); //右边界 stack.push(a

qq_43722914的博客 211

php 求得一组数的排序号,php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中)...

php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中)一、总结1、if(isset($arr[$val])) $arr[$val]++; //1、isset函数2、else $arr[$val]=1; //2、$arr[$val]而非$arr['$val']二、php实现求数组中出现次数超过一半的数字题目描述数组中有一个数字出现的次数超过数组长度...

weixin_42612405的博客 146

剑指offer.53.在排序数字中查找重复数字target的个数

剑指offer.53,在排序数组中查找重复数字target的个数。一看到排序,主要考察对二分法的掌握情况。二分法细节很多,主要细节就在取等或取等之后的操作。

qq_43164662的博客 264
上一篇: 数组插入排序和希尔排序
下一篇: 归并的递归和非递归排序
Arcane Code
博客等级 码龄3年 598粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值