【排序算法 上】带你手撕常见排序 (插入,希尔,选择,堆排序) (动图详解)

news2025/1/19 7:55:26

欢迎来到 Claffic 的博客 💞💞💞

“东风随春归,发我枝上花。”

前言: 

排序是日常生活中极其常见的一种算法,它的功能很简单,就是将数字按照升序/降序排列,最终形成一组有序的数字,不过形成有序数字的过程有多种实现方式,它们各有好坏,接下来,由我带你手撕排序算法。


目录

🥰写在前面 

💐Part1.插入排序 

1.1直接插入排序

1.1.1思想

1.1.2实现 

1.2希尔排序

1.2.1思想

1.2.2实现

🌺Part2:选择排序 

2.1选择排序

2.1.1思想

2.1.2实现

2.2堆排序

2.2.1思想

2.2.2实现 


写在前面 

排序离我们的生活很近,这是一种很重要的算法,比如:

网上购物按价格升序排序

世界500强排名 

排序是常见的,也是重要的,寻找最优的排序能做到优化,所以理解掌握排序是必要的。

下面是要讲解的常见排序:

我们默认实现排升序,一个一个来:

Part1.插入排序 

1.1直接插入排序

1.1.1思想

相信多数人是打牌的,你知道吗,在摸牌的时候,你就悄悄进行了插入排序操作:

这种排序就是新拿到的数字与已有的数字进行比较,确定合适的位置后进行插入操作。

结合动图深度理解: 

可以看到: 

• 当只有一个数字时,没有可比性,可理解为有序;

•  取下一个数字b,与前一个数字a比较,如果b小于a,则需要调整二者的位置,如果a小于b,符合升序,则不需要调整;

•  前一部分排好的数字逐渐增多,取此区间后最近的数字进行挨个比对,不是合适位置,比较过的数字就后移一位,是合适位置,就进行插入操作。

1.1.2实现 

// 插入排序
void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int tmp= a[i];
		int endi = i - 1;
		while (endi >= 0)
		{
			if (tmp < a[endi])
			{
				a[endi + 1] = a[endi];
				endi--;
			}
			else
				break;
			a[endi + 1] = tmp;
		}
	}
}

特征分析:

当原数字越接近有序时,效率越高;

时间复杂度:最好:O(N)  最坏:O(N^2);

空间复杂度:O(1);

稳定性(是否动了相同数字的相对位置)稳定

这个排序看起来效率并不高,希尔在快速排序的基础上进行了优化:

1.2希尔排序

1.2.1思想

本质还是插入排序,只不过希尔做了一个巧妙的处理:引入了 gap ,每隔一个gap分为一组;

先让一部分数字相对有序,再调整下一部分,直至最后有序;

1.2.2实现

// 希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		//gap /= 2;
		gap = gap/3 + 1;

		for (int i = 0; i < n - gap; i++)
		{
			int endi = i;
			int tmp = a[i + gap];
			while (endi >= 0)
			{
				if (tmp < a[endi])
				{
					a[endi + gap] = a[endi];
					endi -= gap;
				}
				else
					break;
				a[endi + gap] = tmp;
			}
		}
	}
}

意:gap是多少并没有明确规定,一般是 gap/3+1  

特征分析:

希尔排序是对直接插入排序的优化,给gap相当于进行预排序,当gap==1时数组就相当有序了,比起直接插入,会快一些;

时间复杂度:最好:O(N^1.25)~O(N^1.3) (参考《计算机程序设计技巧》--Knuth)  最坏:O(N^2);

空间复杂度:O(1);

稳定性:不稳定

Part2:选择排序 

2.1选择排序

2.1.1思想

这种排序方法是我们出厂自带的排序方法,试想:给你一堆乱序的数字,你会怎么排?

通常情况下,我们会从头到尾扫一遍,选出最小的放到最前面,再扫一眼,选出第二大的放到第二位。

这就是选择排序的基本思想。

动图: 

是不是挺符合认知规律的? 

2.1.2实现

// 选择排序
void SelectSort(int* a, int n)
{
	int left = 0, right = n - 1;
	while (left < right)
	{
        // 初始化
		int mini = left;
		int maxi = left;
        // 找到较大/较小值的下标
		for (int i = left+1; i <= right; i++)
		{
			if (a[i] < a[mini]) // 前后顺序会影响结果
			{
				mini = i;
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		Swap(&a[mini], &a[left]);
        // 调试过程中会有left与maxi重叠的情况,这时需要针对这种情况调整
		if (left == maxi)
			maxi = mini;
		Swap(&a[maxi], &a[right]);

		left++;
		right--;
	}
}

特征分析: 

直接选择排序思路易理解,但效率不高,不实用;

时间复杂度:最好:O(N^2)  最坏:O(N^2);

空间复杂度:O(1);

稳定性:不稳定 

2.2堆排序

2.2.1思想

堆排序在往期 什么是堆,如何实现?(附堆排序,TOP-K问题) 中有详解, 

先是建大堆,再是模拟删除操作,这里就不多说啦。

2.2.2实现 

//堆排序
void HeapSort(int* a, int n)
{
	//向下调整(效率更高)
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);

		end--;
	}
}

特征分析:

利用堆的特性,选数快很多,效率较高

时间复杂度:最坏:O(N*logN)  最好:O(N*logN) ;

空间复杂度:O(1);

稳定性:不稳定


总结:

这期是常见排序的前半部分,讲了两类排序:插入排序和选择排序,思想不难,多注意实现中的细节。我打算将后半部分放在下期:交换排序和归并排序。

码文不易 

如果你觉得这篇文章还不错并且对你有帮助,不妨支持一波哦  💗💗💗

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

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

相关文章

Blender3.5 面的操作(一)

目录 1. 面操作1.1 细分面 Subdivide1.2 删除面1.3 挤出面 Extrude1.4 挤出流形1.5 内插面 Inset1.5.1 内插之后选择外侧1.5.2 选择多个面&#xff0c;同时内插操作1.5.3 选择多个面&#xff0c;同时内插选择外侧 1.6 外插1.7 尖分面 Poke Faces1.8 面三角化 Triangulate Faces…

【案例教程】R语言在气象、水文中数据处理及结果分析、绘图实践技术

语言是一门由统计学家开发的用于统计计算和作图的语言&#xff08;a Statistic Language developed for Statistic by Statistician&#xff09;&#xff0c;由S语言发展而来&#xff0c;以统计分析功能见长。R软件是一款集成了数据操作、统计和可视化功能的优秀的开源软件。来…

分布式对象存储服务minio安装和部署

一、服务器安装minio 1.进行下载 下载地址&#xff1a; https://dl.min.io/server/minio/release/linux-amd64/minio2.新建minio安装目录&#xff0c;执行如下命令 mkdir -p /home/minio/data 把二进制文件上传到安装目录后&#xff0c;执行&#xff1a; chmod x minio //…

(leetcode)20. 有效的括号 13. 罗马数字转整数 14. 最长公共前缀

目录 20. 有效的括号 思路 代码 13. 罗马数字转整数 思路 代码 14. 最长公共前缀 思路 代码 20. 有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&…

使用element-plus组件,修改date-picker默认样式

使用深度选择器来修改子组件的样式&#xff0c;今天遇到一个需求&#xff0c;在el-drawer中嵌入的el-date-picker&#xff0c;再一次总结一下深度选择器的用法&#xff0c;需求如下&#xff1a; template内容&#xff1a; <el-drawer size"70%" v-model"dr…

ZVL3网络分析仪

ZVL3 Rohde&Schwarz ZVL3 3G矢量网络分析仪|罗德与施瓦茨 9KHz至3GHz 罗德与施瓦茨Rohde&Schwarz 性能特点&#xff1a; 频率范围 9kHz至3GHz/6 GHz(典型值为5kHz) 测量时间(201个测量点&#xff0c;以校准的双端口) <75ms 数据传输(201个测量点) 在100Mbit/sLAN…

自主机器人概述

自主机器人概述 自主机器人自主机器人应用案例自主机器人相关实验室 自主机器人 自主机器人定义&#xff1a;自主机器人就是一个机器人可以在没有外界干扰的情况下&#xff0c;具备高自动化程度&#xff0c;可以执行任务的机器人。 自主机器人组成&#xff1a;感知-规划-控制…

福建游乐园运营商金生游乐申请纳斯达克IPO上市,募资900万美元

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;来自福建南平的游乐园运营商金生游乐集团Golden Heaven Group Holdings Ltd &#xff0c;&#xff08;以下简称金生游乐&#xff09;&#xff0c;近期已向美国证券交易委员会&#xff08;SEC&…

智能面板小程序如何实现跨端开发,并无缝引入ChatGPT?

如何让开发者更便捷高效地开发面板小程序&#xff1f; 全球化 IoT 开发平台服务商涂鸦智能&#xff08;NYSE&#xff1a;TUYA&#xff0c;HKEX&#xff1a;2391&#xff09;原先提供的是一套基于 React Native (简称 RN) 的面板 SDK&#xff0c;但是随着面板规模的不断增长&am…

职场危机波及到你了吗?社科院与杜兰大学金融管理硕士项目为你重塑核心竞争力

现在职场&#xff0c;危机四伏&#xff0c;每个人都面临着潜在的危机。职场小白&#xff0c;时时忧心自己的工作是否出错&#xff0c;是否能安全度过试用期&#xff1b;面对新人辈出&#xff0c;职场的前辈也担心被拍在沙滩上。面对竞争激烈的职场&#xff0c;你有感到危机吗&a…

[Java]过滤器(Filter)

一、什么是过滤器 过滤器是Servlet的高级特性之一&#xff0c;是实现Filter接口的Java类&#xff01; 过滤器的执行流程&#xff1a; 从上面的图我们可以发现&#xff0c;当浏览器发送请求给服务器的时候&#xff0c;先执行过滤器&#xff0c;然后才访问Web的资源。服务器响应…

nginx简单使用与配置

nginx简单使用与配置 Nginx 是一个高性能的HTTP和反向代理web服务器、一个邮件代理服务器&#xff0c;一个通用的 TCP/UDP 代理服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。 前端可以通过nginx实现以下功能&#xff1a…

【项目实战课】基于Pytorch的YOLOv3工业缺陷检测实战

欢迎大家来到我们的项目实战课&#xff0c;本期内容是《基于Pytorch的YOLOv3工业缺陷检测实战》。所谓项目课&#xff0c;就是以简单的原理回顾详细的项目实战的模式&#xff0c;针对具体的某一个主题&#xff0c;进行代码级的实战讲解。 本次主题 目标检测是最基础的计算机视觉…

利用Resource Hacker简单去除WinRar广告-boldiy

利用Resource Hacker简单去除WinRar广告-boldiy boldiy关注IP属地: 江苏 2022.04.26 18:43:27字数 114阅读 315 下载 Resource Hacker 用软件打开WinRAR.exe 点击展开String Table image.png 打开80&#xff1a;2052 删除1277所在整行&#xff0c;并点击运行&#xff0…

百度地图开发者账号申请

本篇文章要完成的效果 一、百度地图开发者账号申请 官网 &#xff1a; 百度地图开放平台 | 百度地图API SDK | 地图开发 (baidu.com) 没有的话注册一下 一般来说使用过百度云 就有百度账号 点击【控制台】——【我是个人爱好者/学生】 完善个人信息 —— 实名认证 再次返回首…

【逆天应用】如何用Python实现检测和识别车牌号?(详细教程)

文章目录 前言一、创建Python环境二、如何在您的计算机上安装Tesseract OCR&#xff1f;1.导入库2.获取输入2.获取输入3.在输入端检测车牌4.筛选轮廓5.遍历前30个轮廓5.识别检测到的车牌 三,显示输出总结 前言 车牌检测与识别技术用途广泛&#xff0c;可以用于道路系统、无票停…

ChatGPT 速通手册——连续提问和重新生成的作用

连续提问和重新生成的作用 和 ChatGPT 聊天&#xff0c;也是有套路的。我们把给 ChatGPT 输入的问题文本&#xff0c;叫 Prompt&#xff0c;提示词。实际上&#xff0c;传统搜索引擎也有比较相类似的功能。 在 Prompt Learning 提示学习之后&#xff0c;又总结出一种更好的聊…

【虚幻引擎UE】UE4/UE5 新人科普向

一、前言 Unreal Engine是当前最为流行的游戏引擎之一&#xff0c;具有丰富的游戏开发功能和强大的游戏引擎渲染能力。 二、基础 UE5官方文档&#xff1a;UE5官方文档非常详细&#xff0c;介绍了UE5的各个功能和应用&#xff0c;适合入门学习和深入探究。链接&#xff1a;htt…

Pytorch基础 - 0. Tensor数据类型与存储结构

目录 1. Tensor数据类型 2. Tensor存储结构 在讲PyTorch这个系列之前&#xff0c;先讲一下pytorch中最常见的tensor张量&#xff0c;包括数据类型&#xff0c;创建类型&#xff0c;类型转换&#xff0c;以及存储方式和数据结构。 1. Tensor数据类型 (1) 一共包括9种数据类型…

深度学习基础入门篇[六]:模型调优,学习率设置(Warm Up、loss自适应衰减等),batch size调优技巧,基于方差放缩初始化方法。

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…