【排序】插入排序与选择排序详解

请添加图片描述

文章目录

  • 📝选择排序是什么?
    • 🌠选择排序思路
    • 🌉 直接选择排序
      • 🌠选择排序优化
      • 🌠优化方法
        • 🌉排序优化后问题
      • 🌠选择排序效率特性
    • 🌉插入排序
    • 🌠插入排序实现
  • 🚩总结


📝选择排序是什么?

选择排序是一种简单直观的排序算法。它的工作原理如下:在未排序序列中找到最小(大)元素,交换到起始位置,该元素为已排序序列的起始元素,继续在剩余未排序元素中找到最小(大)元素,交换到未排序序列起始位置,重复第二步,直到所有元素均排序完毕。

🌠选择排序思路

在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素,若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换,在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

简单来说:就是在每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

🌉 直接选择排序

例如:定义一个数组 int a[6] = { 9,5,7,2,3,6 };
在这里插入图片描述

  1. 首先:遍历第一趟数组,找出数组的最小值,与第一个数据交换
    在这里插入图片描述
  2. 然后遍历第二趟数组,继续找出最小值,与第二个数据交换
    在这里插入图片描述
  3. 然后遍历第三趟数组,继续找出最小值,与第三个数据交换
    在这里插入图片描述
    如此重复,然后当i等于n-1次选择时排完序,最后一个也有序,排序完成。
    在这里插入图片描述


代码:
上方观察:
选择要找几次?
6个数,一次选择1个,然后有序,第五次选择,5个都有序,最后一个有序。
n个数,选择n-1次,最后一个自然有序。
第一趟选择,下标范围是[0 ~ n-1]
第一趟选择,下标范围是[1 ~ n-1]
第一趟选择,下标范围是[2 ~ n-1]
.
.
.

void Swap(int* px, int* py)
{
	int tmp = *px;
	*px = *py;
	*py = tmp;
}

 void SelectSort(int*arr,int n) 
 {

	for (int i = 0; i < n - 1; i++)//从0开始选,选到n-2次 
	{
		int mini = i;//设最小值是第1位
		for (int j = i + 1; j < n; j++)//首次从1开始到n-1每次比较 
		{								//查找是否有比最小值小的
			mini = arr[j] < arr[mini] ? j : mini;
			
		}

		Swap(&arr[i], &arr[mini]);
	}
}

思路总结:
在一个有n个元素中,进行排序,下标范围是0 ~ n-1,然后我们要在0 ~ n-1,中找到最小的数与0下标的数进行交换,接着在1 ~ n - 1下标中找最小值与1下标交换,然后下次就是2 ~ n - 1找最小值与2交换,每次找到最小值丢到最前面,接着交换,随即下标3,4,5…直到n - 1次选择都排完序,前n-1之前有序了,最后一个也有序。

特性总结:

时间复杂度:
外层for循环从0到n-2,共执行n-1次。内层for循环每次从i+1到n,共执行n-i-1次。所以总时间复杂度为:T(n) = Σ(n-1)(n-i-1) = Θ(n^2)选择排序的时间复杂度是O(n ^ 2)。
空间复杂度:
该算法只使用了一个临时变量mini来记录每次循环找到的最小元素的下标。且不需要额外的数组空间。所以空间复杂度为O(1)。

直接选择排序的特性总结:

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

🌠选择排序优化

🌠优化方法

以上算法是每次找出最小的值放在指定位置,一共要找n-1次。如果我们每次不仅找到最小的值,还找到最大的值,将最小的与左端交换,最大的与右端交换,那么就少了一半的遍历次数,从而提高效率。

  1. 变量begin和变量end是数组的两端,MinMax在0位置,minmax分别找小和大的下标,i=begin+1,让begin+1到end的数都与begin比较。
    在这里插入图片描述

  2. 先交换min与begin位置的数值,再交换max与end位置的数值
    在这里插入图片描述

  3. begin右移,end左移,继续找大找小,继续交换
    在这里插入图片描述

  4. 重复上述操作,直到遍历完所有数组
    在这里插入图片描述

🌉排序优化后问题

若是max的位置与begin重合,则先让beginmin的位置交换,此时原max位置上的最大值已经被交换走,如果直接让end与现max位置交换,交换的值将是错误的。

  1. 当max与begin重合时,min在最小值位置
    在这里插入图片描述
  2. begin先与min的位置交换数据,此时max位置的已经不是最大值了
    在这里插入图片描述
  3. 当max再与end位置交换数据,排序就会出错
    在这里插入图片描述
    解决方法:

当max与begin重合时,先让begin与min交换,此时max原指向的最大值位置已改变,应对max进行修正,让其重新指向数组中真正的最大值位置。然后才能完成end与新max位置元素的交换。

  1. 当max与begin重合,并且begin此时完成了交换,此时最大值已经交换到了min所指向的位置
    在这里插入图片描述
  2. 修改max,让max来到min位置
    在这里插入图片描述
  3. 然后再让max与end交换
    在这里插入图片描述
    代码实现:
void SelectSort(int* a, int n)
{
	int begin = 0, end = n - 1;
	while (begin < end)
	{

		int mini = begin, maxi = begin;
		//选出最小值和最大值的位置
		for (size_t i = begin + 1; i <= end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}

			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}

		Swap(&a[begin], &a[mini]);
		if (maxi == begin)
		{
			maxi = mini;
		}

		Swap(&a[end], &a[maxi]);
		++begin;
		--end;
	}
}

🌠选择排序效率特性

时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:不稳定

🌉插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:**把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。**实际中我们玩扑克牌时,就用了插入排序的思想
在这里插入图片描述
如动图:
请添加图片描述
步骤:

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5

通过不断地将当前元素插入到已经排好序的有序序列中,直到全部元素排完,即完成整个排序过程。

🌠插入排序实现

思路:第一个数天然有序,第二个数与代排有序序列第一个比较,小与插入,第三个数与前面两个元素比较,依次比较前面元素,然后比较完依次将后面元素依次插入到前面有序序列中,直到序列停止。
在这里插入图片描述
代码如下:

void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		//[0,end]  end+1
		 //end记录当前要插入的元素位置 
		 //end+1就是待插入元素的下标
		int end = i; 
		int temp = arr[end + 1];//temp临时存储arr[end+1]这个待插入元素
		while (end >= 0)
		{
			//如果temp小于arr[end],说明待插入元素应该插入在这个位置
			//将元素后移一位
			if (temp < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			//否则直接跳出循环
			else
			{
				break;
			}
		}
		//将待插入元素插入到正确位置
		arr[end + 1] = temp;
	}
}

时间复杂度:
最坏情况下为O(N*N),此时待排序列为逆序,或者说接近逆序
最好情况下为O(N),此时待排序列为升序,或者说接近升序。
元素集合越接近有序,直接插入排序算法的时间效率越高
空间复杂度:O(1),它是一种稳定的排序算法


🚩总结

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何一键下载微信视频号的视频至本地电脑

社交媒体平台上的短视频已经成为我们获取信息和娱乐的重要来源&#xff0c;尤其是微信视频号。这个平台汇聚了丰富多样的内容&#xff0c;从生活分享到专业知识&#xff0c;应有尽有。然而&#xff0c;有时我们可能希望将这些有趣的或有用的视频保存到本地以便离线观看或分享给…

【免费】如何考取《鲸鸿动能广告初级优化师》认证(详细教程)

鲸鸿动能广告初级优化师认证考试PC网址 初级&#xff1a;鲸鸿动能广告初级优化师认证-华为开发者学堂 (huawei.com) 注&#xff1a;免费认证&#xff0c;里面包含免费的课程&#xff0c;浏览器用Edge。 文章目录 鲸鸿动能广告初级优化师认证考试网址 前言 一、备考流程 二…

PCL点云处理之最小中值平方(Lmeds法)拟合平面(二百三十四)

PCL点云处理之 最小中值平方法(Lmeds)拟合平面(二百三十四) 一、算法介绍一、拟合原理二、具体实现1.代码2.结果一、算法介绍 (本文提供详细注释,输出拟合平面参数和平面点云) Lmeds(Least Median of Squares)是一种统计学方法,用于拟合数据并减少异常值对拟合结果…

MySQL数据库 - 事务

1. 事务的概念 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&#xff0c;在人员管理系统中&#xff0c; 要删除一个人员&#xff0c;即需要删除人员的基本资料&#xff0c;又需要删除和该人员相关的信息&#xff0c;如信箱&#xff0c; 文章等等。这样&#x…

总结 | vue3项目初始化(附相应链接)

如何运行 vue 项目&#xff1a;vscode运行vue项目_vscode启动vue项目命令-CSDN博客 vue3项目搭建 目录管理 git管理&#xff1a; 目录调整&#xff1a; 克隆项目&#xff0c;绑定自己的库&#xff1a;[git] 如何克隆仓库&#xff0c;进行项目撰写&#xff0c;并绑定自己的…

kotlin中使用ViewBinding绑定控件

kotlin中使用ViewBinding绑定控件 什么是ViewBinding&#xff1f; View Binding是Android Studio 3.6推出的新特性&#xff0c;主要用于减少findViewById的冗余代码&#xff0c;但内部实现还是通过使用findViewById。通过ViewBinding&#xff0c;可以更轻松地编写可与视图交互…

数据库专题(基础)

前言 本专题主要记录自己最近学的数据库&#xff0c;有兴趣一起补习的可以一起看看&#xff0c;有补充和不足之处请多多指出。希望专题可以给自己还有读者带去一点点提高。 数据库基本概念 本模块有参考&#xff1a;数据库基本概念-CSDN博客 数据库管理系统是一个由互相关联的…

Pake一键打包,轻松构建桌面级应用!

Pake&#xff1a;顷刻之间&#xff0c;智能封装——WEB到桌面瞬间联通&#xff0c;让网站应用像搭积木般部署 - 精选真开源&#xff0c;释放新价值。 概览 Pake&#xff0c;作为一款新颖且极具创新性的桌面应用开发框架&#xff0c;凭借其独特的技术路径和高效的实现方式&…

【python】flask请求钩子,主动抛出异常与异常捕获

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

头部银行 AI 落地实践|数据应用赋能经营管理闭环

数据要素在银行各业务领域和流程中发挥着至关重要的作用&#xff0c;面对激烈的市场竞争和客户需求&#xff0c;银行越来越注重从数据管理中寻求效益和增值&#xff0c;深入洞察市场动态和客户需求&#xff0c;从而优化其产品与服务&#xff0c;提升运营效率和市场营销的成效。…

《妈妈是什么》笔记(二) 让孩子自己做选择

经典摘录 孩子也会需要独立的空间做事情&#xff0c;求独立、求空间、求私隐 对于不管因为什么&#xff0c;别人在受到肯定和赞赏的时候&#xff0c;会对我们自己的心理带来因“比较”而产生的不适感甚至嫉妒感&#xff0c;进而在行为上影响了我们自己的节奏&#xff0c;产生一…

RabbitMQ是怎么做消息分发的?

标题RabbitMQ是怎么做消息分发的&#xff1f; RabbitMQ一共有6中工作模式&#xff08;消息分发模式&#xff09;&#xff0c;分别是简单模式、工作队列模式、发布订阅模式、路由模式、主题模式、以及RPC模式。 简单模式是最基本的工作模式&#xff0c;也是最简单的消息传递模…

[Java、Android面试]_11_线程的启动方式和区别

文章目录 1. 继承Thread类2. 实现Runnable接口3. 实现Callable接口4. 使用Executor框架4. 四者的区别 本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于…

DXP学习2- 绘制电气图【实验】

目录 一、实验目的 二、实验原理 1、创建一个新的项目文件。 2、新建原理图文件 3、设置原理图选项 4、放置元器件 5、其他电路元素的放置 6、对所有电路元素属性参数值的修改 三、实验设备 四、实验内容 1、绘制实验图2-1 元器件所在位置&#xff1a; 1&#xff0c;…

炒伦敦金大师级的交易技术

交易中的反身性由投资大师索罗斯提出&#xff0c;简单来说&#xff0c;它所描述的是投资者与市场之间那种奇妙的互动和互相影响的关系。大家可以把伦敦金市场趋势&#xff0c;想象成一个很大的舞台&#xff0c;它会影响和决定投资者的心理预期和决策。 而投资者的心理预期和决策…

【C++】Qt:WebSocket客户端示例

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍WebSocket客户端示例。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&…

k8s-kubectl命令详解、Pod创建过程、Pod的生命周期、定制Pod、资源对象文件

集群管理 一、如何管理集群 kubectl是用于管理Kubernetes集群的命令行工具 二、语法格式&#xff1a; kubectl [command] [TYPE] [NAME] [flags] command&#xff1a;子命令&#xff0c;如create&#xff0c;get&#xff0c;describe&#xff0c;delete type&#xff1a;…

redis集群数据一致性如何保证?

一般的做法是对key进行hash&#xff0c;比如有4台机器&#xff0c;就对4取模。 这样的坏处是增加或者减少机器的时候&#xff0c;会有大量数据进行迁移。 业界做法是用一致性哈希算法&#xff0c;将机器节点的ip值&#xff0c;对一个很大的数取模比如2^32&#xff0c; 用一个…

Prometheus 配置Basic auth认证

官方配置说明&#xff1a; Basic auth | Prometheus 一、生成密码加密串 Prometheus于2.24版本&#xff08;包括2.24&#xff09;之后提供Basic Auth功能进行加密访问&#xff0c;在浏览器登录UI的时候需要输入用户密码&#xff0c;访问Prometheus api的时候也需要加上用户密…

优质的短效HTTP代理具备什么优点?

随着网络时代的蓬勃发展&#xff0c;数据的获取与处理成为了企业决策和市场竞争的关键。在这场数据的角逐中&#xff0c;优质的短效HTTP代理脱颖而出&#xff0c;备受业界瞩目。优质的短效HTTP代理&#xff0c;提供了稳定的网络连接和匿名性&#xff0c;更为数据采集提供了关键…