数据结构之排序【冒泡排序和快速排序之一的实现及分析】内含动态演示图

news2024/12/26 11:03:19

引言:

今天分享一下一点小事迹,自从从学校回到家里,我已经好久没睡上一个好觉了,因为真的冷,莫名被窝总是感觉很冷,然后穿着袜袜的脚也是冰凉,所以每次早晨要起床的时候总是感觉非常的冷,更牛的是我昨天直接被冷醒了,可能是因为学校的床没有那么大,所以不容易把热量散发掉,所以每次在学校都睡的非常的香,所以今天我决定睡在地板上(当然是床和衣柜之间的地板),这样我就可以实现小床睡觉了(明天的这个时候,准时汇报具体睡觉情况),并且现在是北京时间 2022/12/25/22:25 ,我还有一篇期末论文没有写,我毅然决然的选择先搞定这个,其它的再说吧!
天大寒,砚冰坚,手指不可屈伸,码字还是不易,所以引言就这样吧!今天我们学习一下冒泡排序和快速排序,当然重点是快速排序(冒泡排序效率低,所以我们学一下思想就行)

1.冒泡排序

for循环和while循环代码实现并且进行它们之间的比较对比

动图演示:
在这里插入图片描述

像排序这种类型的东西,以后我们可以不要直接来就靠我们的记忆去写,可以先按照基本原理来
比如,此时我们就是想要把一个数组中的最大的那个数放到数组的最后一个位置处,应该怎样写,
怎样通过多躺来控制单趟,怎样控制次数和边界
然后此时的这个for循环代表多躺,用来控制我的单趟(所以我的单趟是思想,多躺是和单趟相似的)

void BubbleSort(int* arr, int n)
{
	int j;
	for (j = 0; j < n - 1; j++)
	{
		int exchange = 0;
		int i;
		for (i = 0; i < n - 1 - j; i++)//遍历
		{
			if (arr[i] > arr[i + 1])//每个数比较,大的数往后走
			{
				Swap(&arr[i], &arr[i + 1]);
				exchange = 1;
			}
		}
		
		if (exchange == 0)//此时就是防止数组已经是有序的,然后还进行比较,所以我们为了防止,就可以这样写,交换了就不满足这个条件,就正常比较,没有交换就满足这个条件,就跳出循环
		{
			break;
		}
	}
}

所以只要是有思想代码怎么写都是可以的,单趟(目的:为了让最大值到达数组的最后一个位置)
多躺:控制单趟和边界的处理

void BubbleSort(int* arr, int n)
{
	int end = n;
	while (end > 0)
	{
		int i;
		for (i = 0; i < n - 1; i++)
		{
			if (arr[i] > arr[i + 1])
			{
				Swap(&arr[i], &arr[i + 1]);
			}
		}
		//写完单趟,然后我为了控制次数,可以用上述的for循环,也可以直接用while循环,只要把比较的次数给控制好了,怎样写都行
		end--;//反正就是n次而已
	}
}

所以总的来说对比两种循环,多躺就是用来控制单趟的边界的(就是控制什么时候要继续,什么时候停下来,然后循环几次之类的问题)

2.重点:快速排序

2.1 快速排序(方法很多(主要涉及递归和非递归),复杂)
快速排序原理:快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

将区间按照基准值划分为左右两半部分的常见方式有: 1.挖坑法

上述的原理:1. 第一步就是要找一个key(关键值),6 5 1 2 7 9 3 4 10 8 => 此时就把arr[0]作为我的key(也就是把这个key作为一个pivot(坑)),然后把比key大的放在key的右边,比key小的放在key的左边

2.2 挖坑法的具体原理:我们把arr[0]的值给拿走了,此时key处就是一个坑(就是空位置的意思) ,

然后我就去遍历key右边的数组元素,比较,把比key小的数给放到arr[0]位置处,然后把我们刚刚找

到的那个比key小的元素的位置重新赋值为坑(因为此时这个元素已经是没用的了,这个位置就可以

相当于是空),然后再去遍历key左边的数组元素,把key左边比key大的数放到新的坑的位置,然后

把刚刚key左边找到比key大的元素的位置重新赋值为坑,然后重复这个步骤,此时我就实现单趟排序

把比key大的放在key的右边,比key小的放在key的左边,并且将key放在正确的位置处 => 5 1 2 4 3

6 9 7 10 8 变成这样就是我的单趟的目的 (虽然说是单趟但是实际是一个循环),只是后面还会涉

及到递归而已

具体动图演示:
在这里插入图片描述
然后我们以下面的图示来进行进一步的理解:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
右边按照同样的操作进行,即可把排序完成(即我的分治递归)

2.3 代码实现(注释详解每一步)

//void QuickSort(int* arr, int n)
//为了使用我的分治递归现在我的这个函数的作用就不单单是一个值了,是一段数组中的值,所以就不可以按照上面这样写,应该要写成下面的形式
void QuickSort(int* arr, int left, int right)
{
	if (left >= right)//递归的停止条件(就是当我的区间只有一个值或不存在)大于表示只有一个值,等于表示区间不存在
	{
		return;
	}
	//int begin = 0;//就是最左边的意思
	//int end = n - 1;//就是最右边的意思
	//此时为了实现分治递归,我们就要把上面的begin和end写成下面的这个样子
	int begin = left;
	int end = right;
	int pivot = begin;//按照原理,此时的这个pivot可以给最左边的位置或者最右边的位置
	int key = arr[begin];//按照原理,此时的这个pivot可以给最左边的位置或者最右边的位置
	while (begin < end)//因为待会会进行begin++ end--的操作,所以当它们相等之后,我就已经实现了把比key大的放在key的右边,比key小的放在key的左边,所以只要begin!=end 这个循环就要继续
	{
		//右边找小,放到左边(在key的右边找,自然是从最右边开始)
		while (begin < end && arr[end] >= key)
		{
			end--;
		}
		//程序来到这里说明我找到比key小的元素了(然后此时按照原理:就是把找到的这个值放到key的pivot位置,然后重新把这个找到的元素的位置赋值成pivot(便于待会把左边的元素放过来))
		arr[pivot] = arr[end];
		pivot = end;

		//此时我的左边的坑被右边的元素占据了,所以现在就要在左边找比key大的数据放到右边的坑中,然后左边再形成一个坑
		while (begin < end && arr[begin] <= key)
		{
			begin++;
		}
		//程序来到这个位置说明我找到比key大的元素了,然后把它放到右边的坑中就行,顺便把自己原来的位置重新赋值为坑,使左边又有一个新的坑,便于待会后面比key小的值放进来
		arr[pivot] = arr[begin];
		pivot = begin;
	}

	//此时程序来到这个位置就是说明:begin和end相遇了(此时就可以把我的key的位置直接放到最后的这个pivot中)
	pivot = begin;//此时就是找最后一个坑的位置
	arr[pivot] = key;//然后把key放到这个坑里面去

	//此时这边我们为了可以使用我的分治递归,按照原理就是要把这个数组分成三部分:
	//[left,right]
	//                                                [pivot]
	//                                                   |                                     
	//[left,pivot-1][pivot][pivot+1,right] =>  5 1 2 4 3 6 9 7 10 8
	//因为此时只要左子区间有序了,右子区间有序了,我的整个数组就有序了,所以此时就是把左子区间和右子区间都拿去递归就行了
	QuickSort(arr, left, pivot - 1);
	QuickSort(arr, pivot + 1, right);

}

3.快排测试

在这里插入图片描述

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

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

相关文章

shell基础使用

一、hello world 首先建立一个tmux vim test.sh //再创建一个test.sh文件 进入文件后&#xff0c;创建一个如下命令&#xff0c;指明bash为脚本解释器 #! /bin/bash //相当与c头文件echo "hello world"运行方式 1.作为可执行文件 acs9e0ebfcd82d7:~$ chmod x test.s…

我是如何将2千万StackOverflow问答翻译成中文的?

大家好&#xff01;大家觉得如果需要翻译SO上全部问答可以怎么做呢&#xff1f;我讲讲我是怎么的&#xff0c;大家看看做得怎么样。 自我介绍 我是一名有10年开发经验的老程序员。做过大数据&#xff0c;做过Java程序员&#xff0c;也做过算法工程师&#xff0c;目前是一名大厂…

Spring Security的项目中集成JWT Token令牌安全访问后台API

Spring Security的项目中集成JWT Token令牌安全访问后台API引言JWT 简介jwt token 的适用场景jwt 的结构完整jwtjwt 的使用方式客户端获取jwt令牌访问受保护资源的具体流程Spring Security 安全框架下使用jwt token新建一个spring boot项目加入spring security 和 jwt 相关依赖…

五、传输层(二)UDP

目录 2.1 UDP概述 2.2 UDP的首部格式 2.3 UDP校验 2.1 UDP概述 UDP无须建立连接。因此不会引入建立连接的时延。 UDP为无连接状态。因此当服务器使用UDP时&#xff0c;一般能支持更多的活动客户机。 UDP分组首部仅有8B的开销&#xff0c;而TCP有20B的首部开销。 应用层…

后端思维篇:如何抽个上报模板

前言 大家好&#xff0c;我是田螺。 我的后端思维专栏好久没更新啦&#xff0c;本文是后端思维专栏的第六篇哈。我的整个后端思维专栏都是跟日常工作相关的哈。 最近刚好优化了安全上报这块的代码&#xff0c;抽了一个基础模板&#xff0c;看起来挺优雅的。所以今天手把手教…

〖产品思维训练白宝书 - 产品思维认知篇⑤〗- 学习 [产品思维] 需要做哪些准备?

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

php wampserver的使用配置

php wampserver的使用配置wampserver1.php时区配置2.修改apache服务器端口号3.设置起始页4.设置web服务器主目录5.设置虚拟目录wampserver WampServer是Windows Apache Mysql PHP集成安装环境&#xff0c;在Windows操作系统下的apache、php和mysql的服务器软件。 1.php时区配…

RabbitMQ 第二天 高级 7 RabbitMQ 高级特性 7.2 Consumer Ack

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第二天 高级7 RabbitMQ 高级特性7.2 Consumer Ack7.2.1 Consumer Ack7.2.2 Consumer Ack 小结7.2.3 消息可靠性总结第二天 高级 7 RabbitMQ 高级特性 7.2 Consumer Ack 7.2.…

12.25日周报

周报 代码行数&#xff1a; 周一 704 周二 481 周三 571 周四 589 周五 595 周六 520 周日 537 遇到的问题&#xff1a; 没用过的方法AtomicInteger Insert Proto currentTimeMillis RequestParam BufferedReader UriComponents RestTemplate OSS 不清楚在…

公众号开发(2) —— 盛派.net SDK + vue搭建微信公众号网页开发框架

需求&#xff1a;通过微信公众号菜单跳转到手机端网页&#xff0c;跳转后通过微信授权登录获取微信公众号用户的OpenId&#xff08;用户关注公众号后&#xff0c;用户在公众号的唯一凭证&#xff09;&#xff0c;通过OpenId和后台数据库用户信息绑定起来并实现一些业务逻辑。 技…

基于51单片机的电子闹钟设计

使用的单片机是 STC89C52 此设计可以 年 月 日 时 分 秒显示和闹钟功能 能通过8个按键自由调整 时 分 秒 闹钟响铃时间 带复位按键&#xff0c;要是模块抽风&#xff0c;摁复位按键即可&#xff01; 使用 LCD16020A 屏幕显示 屏幕电路设有电位器&#xff…

Tableau可视化设计案例-07 多边形地图和背景图地图

Tableau可视化设计案例 本文是Tableau的案例&#xff0c;为B站视频的笔记&#xff0c;B站视频 参考&#xff1a;https://www.bilibili.com/video/BV1E4411B7ef 参考&#xff1a;https://blog.csdn.net/lianjiabin/category_9826951.html 数据下载地址为&#xff1a;https://do…

Java项目:springboot药品管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目属于前后端分离的项目&#xff0c;分为两个角色药品管理员和取药处人员 药品管理员&#xff1a; 登录、退出、药品信息录入、药厂信息录入…

Huawei Certified ICT Professional work (一)

文章目录一&#xff0c; 要求二&#xff0c;搭建拓扑图三&#xff0c;配置接口IP和环回IP四&#xff0c;进行RIP版本的配置并且宣告网段五&#xff0c;实现不同版本的连通&#xff0c;在交界处配置对端的版本号六&#xff0c;R3访问R7的环回地址走R5&#xff0c;改变R4的度量值…

Java项目:SpringBoot+MyBatis送水公司管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 这个项目是一个基于SpringBootMyBatis的送水公司管理系统 管理员权限包括&#xff1a; 客户管理 送水工管理 送水历史管理 计算工资 统计送水数…

79页智慧应急指挥平台1 6 N体系建设方案

【版权声明】本资料来源网络&#xff0c;仅用于行业知识分享&#xff0c;供个人学习参考&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间进行删除&#xff01; 完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 行业专网解决…

ARM_SMMU_下

SMMU驱动代码分析 本文主要分析linux kernel中SMMUv3的代码(drivers/iommu/arm-smmu-v3.c) linux kernel版本是linux 5.7, 体系结构是aarch64 SMMU的作用是把CPU提交给设备的VA地址&#xff0c;直接作为设备发出的地址&#xff0c;变成正确的物理地址&#xff0c;访问到物理内…

五、传输层(一)传输层的功能

目录 1.1传输层的主要功能 1.2传输层的寻址与端口 1.2.1端口的作用 1.2.2端口号 1.2.3套接字 1.3无连接服务与面向连接服务 1.1传输层的主要功能 物理层、数据链路层和网络层共同解决了主机通过异构网络互联起来所面临的问题&#xff0c;实现了主机到主机的通信。然而在…

【iOS】CAlayer的认识与使用

什么是CALayer CALayer是UIView里的一个图层&#xff0c;其主要功能是负责显示视图与动画。CALayer和UIView 功能是一致的、 不过因为其 更加底层 所以 CALayer 有一些接口、 UIView 里面没有。 CALayer与UIView UIView&#xff1a;用于管理视图的容器。每次创建UIView对象时…

当我阳了之后是如何用Python来自动买药的

人生苦短&#xff0c;我用Python序言准备工作代码实战序言 哈喽兄弟们&#xff0c;我是郑再阳&#xff0c;马上要成杨过了&#xff01; 读者&#xff1a;在下羊了个羊&#xff01; 最近总是听说哪里哪里阳了&#xff0c;哪个公司又团灭了&#xff0c;emmm~ 于是乎看了几天后…