八大排序——快速排序

news2024/11/24 10:32:16

在这里插入图片描述
Hello,大家好,今天分享的八大排序里的快速排序,所谓快速排序是一个叫霍尔的人发明,有很多人可能会觉得为什么不叫霍尔排序,其中原因就是因为它快,快速则体现了它的特点,今天我们就来讲一下快速排序,现在开始我们的学习吧。

快速排序

1.基本思想
通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
实现逻辑

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

① 从数列中挑出一个元素,称为 “基准”(pivot),
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

我们来看一下它的图是怎么实现的

在这里插入图片描述
首先我们给定它一个数组,并且定义左边为left,右边为right,然后我们的有个中间值,中间值这里我们就叫它为k,定义这个k是从left开始,当然我们也可以从right开始,等一下会来讲原因,现在我们只要看懂它的图就行
在这里插入图片描述
因为是从左边开始,所以要从右边先走,原因是我们这样才能确定left和right相遇的时候的值一定比k的值小,这里再详细展开讲解一下,我们的left和right相遇有两种可能,一种是left和right相遇,这个时候相遇是怎样的呢,因为right先走,遇到比k小的时候停下来,然后left又开始走,除非遇到比l大的值才会停下,否则就继续,但是我们还有一个结束条件那就是left要小于right,所以如果left没有找到比k大的值,他们就会相遇,那这样的话,因为我们right找到小的值了,所以最后k肯定比right所指向的值要大,还有一个就是我们right遇到left,那同样的道理,说明我们的right没有找到比k大的值,所以相遇之后也是一样的道理,结论就是相遇的值一定比k指向的值小。那我们再继续来看图

在这里插入图片描述
这个时候我们的right找到比k小的值,然后才开始动left,那我们现在开始动left

在这里插入图片描述
left也找到了,那现在就是交换它们的,这里我们用一个swap函数就可以了,因为后面还需要用到swap这个函数的,交换之后变成这样的
在这里插入图片描述
可以看到先在我们已经开始交换,我们找值需要一个两个while,外面还需要一个大while控制

那我们现在可以继续开始动right了
在这里插入图片描述
这下又找到了
开始动left

在这里插入图片描述
那现在我们需要交换他们
在这里插入图片描述
现在我们也交换好了,现在right在走一步就会爆炸(小编是小黑子,实锤了),这个时候循环就应该结束

在这里插入图片描述
我们需要做的就是在循环外面再进行k和left的交换

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
int PartSort(int* a,int left, int right)
{
	int k = left;
	while (left < right)
	{
		while ( a[right] > a[k])
		{
			right--;
		}
		while ( a[left] < a[k])
		{
			left++;
		}
		
		swap(&a[left], &a[right]);
	}
	swap(&a[left], &a[k]);
	return left;
}

这里其实会有问题,有两个问题,一个是会存在越界,一个就是会出现死循环,先讲一下死循环的例子,比如我们再第一次找left和right的值,这两个值的大小是相等的,那他们进行交换之后,left和right的值就不会变了,因为循环他们进不去了,所以要加一个等于的条件就行了,还有就是越界,我们之前讲过越界就像查酒驾一样,是有随机性的,为什么会越界,是因为right可能一直找不到小的值,然后就会比left还小,所以我们只需要加上一个条件就行了
看看代码

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
int PartSort(int* a,int left, int right)
{
	int k = left;
	while (left < right)
	{
		while (left < right && a[right] >= a[k])
		{
			right--;
		}
		while (left < right && a[left] <= a[k])
		{
			left++;
		}
		
		swap(&a[left], &a[right]);
	}
	swap(&a[left], &a[k]);
	return left;
}

现在就是这只是我们走了一遍并不能实现将他们变成有序数列,所以这里我们就可以用递归进行遍历,怎么进行遍历,为什么能进行遍历呢,我们来分析

在这里插入图片描述
会这样分成左边和右边,然后再左边和右边再进行我们上面的操作,那是不是和二叉树很 相似的,所以我们递归实现一下,这里不过多的讲解,等我更新二叉树的文章后,大家可能看起来就明白了

void QuickSort(int* a, int begin,int end)
{	
	if (begin >= end)
		return;
	int ret = PartSort(a, begin, end);
	QuickSort(a, begin, ret - 1);
	QuickSort(a, ret + 1, end);
}

完整代码加测试代码

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
int PartSort(int* a,int left, int right)
{
	int k = left;
	while (left < right)
	{
		while (left < right && a[right] >= a[k])
		{
			right--;
		}
		while (left < right && a[left] <= a[k])
		{
			left++;
		}
		
		swap(&a[left], &a[right]);
	}
	swap(&a[left], &a[k]);
	return left;
}

void QuickSort(int* a, int begin,int end)
{	
	if (begin >= end)
		return;
	int ret = PartSort(a, begin, end);
	QuickSort(a, begin, ret - 1);
	QuickSort(a, ret + 1, end);
}

#include<stdio.h>
int main()
{
	int arr[] = { 6,1,2,7,9,3,4,10,8 };
	QuickSort(arr, 0, sizeof(arr) / sizeof(int) - 1);
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
反正最后排序成功了,这个挡住了一部分结果,我换个大的
在这里插入图片描述
好好好,今天的学习就到这吧,拜拜。。。。

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

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

相关文章

李宏毅-hw5-translation-有关transformer、seq2seq的探索

一、ppt研读&#xff1a; 1.关于这个 input Embedding 的内容: 2.关于Positional Encoding&#xff1a; 二、慢慢积累&#xff0c;一点点阅读代码&#xff1a; 虽然这次的模块挺多的&#xff0c;但是&#xff0c;这样也就意味着&#xff0c;把这个内化为自己的&#xff0c;就…

【面试经典150 | 数组】合并两个有序数组

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;合并排序方法二&#xff1a;双指针方法三&#xff1a;原地操作-从前往后方法四&#xff1a;原地操作-从后往前 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章…

Axure RP 9 for Mac/Windows图文安装教程

Axure RP 9是一款一款专业级快速产品原型设计工具&#xff0c;使用它可以让用户快速、高效创建应用软件或Web网站的线框图、流程图、原型和规格说明文档。 Axure RP 9 for Mac采用了极简主义的设计&#xff0c;界面布局更加清爽简洁&#xff0c;操作也非常简单&#xff0c;并且…

系统架构设计专业技能 ·操作系统

现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 点击进入系列文章目录 系统架构设计高级技能 操作系统 一、操作系统概述二、进程管理2.1 进程概念2.2 进…

VSCode中配置命令行参数

VSCode中配置命令行参数 在跑程序调试的时候&#xff0c;可以直接使用脚本运行程序&#xff0c;这个时候调试代码只能用pdb ,我觉得不太习惯&#xff0c;而且感觉不是很好&#xff0c;所以想这能不能将运行程序的脚本中的命令直接配置到vscode上&#xff0c;就有了这篇记录。 …

oCPC实践录 | oCPC转化的设计、选择、归因与成本设置(2)

在oCPC实践录 | oCPC转化的设计、选择、归因与成本设置&#xff08;1&#xff09;中初步介绍了平台侧和广告主侧的转化设计&#xff0c;这篇文章介绍平台侧和广告主怎么选择转化目标&#xff0c;归因与成本控制。 一 上周受公司增长部门的同事邀请做了一场分享和交流&#xf…

Cesium 制作风流场,制作风场可视化

需求 Cesium 制作风场 预览 分析 以下是开发中参考的几个博主的案例 博客一&#xff1a;风场热力图博客二博客三 风场数据准备&#xff0c;data.json 由于数据量过大&#xff0c;我这边只做格式展示&#xff0c;想要完整 json 文件&#xff0c;可以在我的资源里获取 […

A Yet Another Remainder The 2022 ICPC Asia Regionals Online Contest (II)

PTA | 程序设计类实验辅助教学平台 题目大意&#xff1a;有一个n位长的隐藏数x&#xff0c;从高位到低位依次标号为1到n&#xff0c;sum[i][j]表示从第i为开始每j位上的数的和&#xff0c;有q次询问&#xff0c;每次给出一个100以内除了5以外的质数p&#xff0c;问这个数%p等于…

免费版Photoshop2024智能人像磨皮插件

Portraiture是一款智能磨皮插件&#xff0c;为Photoshop和Lightroom添加一键磨皮美化功能&#xff0c;快速对照片中皮肤、头发、眉毛等部位进行美化&#xff0c;无需手动调整&#xff0c;大大提高P图效率。全新4版本&#xff0c;升级AI算法&#xff0c;并独家支持多人及全身模式…

企业架构LNMP学习笔记32

企业架构LB-服务器的负载均衡之LVS实现&#xff1a; 学习目标和内容 1&#xff09;能够了解LVS的工作方式&#xff1b; 2&#xff09;能够安装和配置LVS负载均衡&#xff1b; 3&#xff09;能够了解LVS-NAT的配置方式&#xff1b; 4&#xff09;能够了解LVS-DR的配置方式&…

基于SSM的生鲜电商系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux高性能服务器编程 学习笔记 第一章 TCP/IP协议族

现在Internet使用的主流协议族是TCP/IP协议族&#xff0c;它是一个分层、多协议的通信体系。 TCP/IP协议族包含众多协议&#xff0c;我们只详细讨论IP协议和TCP协议&#xff0c;因为它们对编写网络应用程序有最直接的影响。如果想系统学习网络协议&#xff0c;RFC&#xff08;…

LeetCode147之对链表进行插入排序(相关话题:链表)

题目描述 给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。 插入排序 算法的步骤: 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列…

深度解析自然语言处理之篇章分析

在本文中&#xff0c;我们深入探讨了篇章分析的概念及其在自然语言处理&#xff08;NLP&#xff09;领域中的研究主题&#xff0c;以及两种先进的话语分割方法&#xff1a;基于词汇句法树的统计模型和基于BiLSTM-CRF的神经网络模型。 关注TechLead&#xff0c;分享AI全维度知识…

LLM推理优化技术综述:KVCache、PageAttention、FlashAttention、MQA、GQA

LLM推理优化技术综述&#xff1a;KVCache、PageAttention、FlashAttention、MQA、GQA 随着大模型被越来越多的应用到不同的领域&#xff0c;随之而来的问题是应用过程中的推理优化问题&#xff0c;针对LLM推理性能优化有一些新的方向&#xff0c;最近一直在学习和研究&#xf…

react-native实现 TextInput 键盘显示搜索按钮并触发回调

<TextInput returnKeyType"search"returnKeyLabel"搜索"onSubmitEditing{e > {toSearch(keyword);}} /><SearchBarref{serachBarEl}placeholder"请输入"onChangeText{handleChangeSearch}value{search}onSubmitEditing{handleSearch…

群晖NAS教程(二十四)、利用ContainerManager安装jellyfin

群晖NAS教程(二十四)、利用ContainerManager安装jellyfin 一、下载nyamisaka/jellyfin镜像 二、运行jellyfin容器并配置 容器名称可以随便填写 这里映射端口设置为8096&#xff0c;并且映射了两个配置文件夹和一个电影的目录。 点击完成。 这里看到已经运行起来了。 三、jelly…

C# 参数名加冒号,可以打乱参数顺序

今天看到Python有这种语法&#xff0c;参数名后面跟着等号写参数&#xff0c;联想到前几天用到的Serilog&#xff0c;好像有个参数名加冒号的写法&#xff0c;搜索了一下&#xff0c;果真有这种用法。 函数特别大的时候&#xff0c;用这种方法很直观&#xff0c;而且参数可以打…

你真的了解 Docker 日志吗?

目录 前言排查总结 前言 今天服务器发送了磁盘告警通知&#xff0c;于是打开了尘封已久的电脑连上了公司服务器&#xff0c;服务器跑的是一个 Docker Swarm 集群&#xff08;正是集群中的某一台服务器发生告警&#xff09;&#xff0c;告警的服务器上运行了多个游戏后台程序。…

密室逃脱小游戏

欢迎来到程序小院 密室逃脱 玩法&#xff1a; 判断可生存的空间&#xff0c;鼠标点击屏幕进行人物左右移动&#xff0c;躲避闸道进行生存&#xff0c;每进行一次关卡都会有分数统计&#xff0c;赶紧去闯关吧^^。开始游戏https://www.ormcc.com/play/gameStart/176 html <c…