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

请添加图片描述

文章目录

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


📝选择排序是什么?

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

🌠选择排序思路

在元素集合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/487232.html

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

相关文章

总结虚函数表机制——c++多态底层原理

前言&#xff1a; 前几天学了多态。 然后过去几天一直在测试多态的底层与机制。今天将多态的机制以及它的本质分享给受多态性质困扰的友友们。 本节内容只涉及多态的原理&#xff0c; 也就是那张虚表的规则&#xff0c;有点偏向底层。 本节不谈语法&#xff01;不谈语法&#x…

每日一题|djwcb【算法赛】|字符串快速幂

每日一题|djwcb【算法赛】 djwcb 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 djwcb 注意&#xff1a; 快速幂字符串&#xff0c;看…

js获取cookie

js获取cookie 前言实现讲解特别注意&#xff1a; 前言 主要是通过document.cookie来进行实现的 实现讲解 首先通过document.cookie 来获取到所有的cookie 然后通过分号进行分割成list 然后循环list,将list中的字符串通过首个等号进行分割然后和指定的cookie名进行比对然后返…

Android 导航方式切换

1.导航栏样式目前有&#xff0c;三键导航&#xff0c;也有全局手势导航&#xff0c;具体的设置是在setting里 setting里对应的 代码逻辑在packages\apps\Settings\src\com\android\settings\gestures\SystemNavigationPreferenceController.java static boolean isOverlayPacka…

芯片设计工程师必备基本功——《Verilog+HDL应用程序设计实例精讲》

进入芯片行业需要学习哪些基本功呢&#xff1f;其实芯片设计工程师的技能是通过多年的经验学习的。在您开始作为芯片设计工程师工作之前&#xff0c;很难给出一个需要的全面的单一列表&#xff0c;也不可能学习所有内容。话虽如此&#xff0c;但您开始芯片设计师职业生涯时必须…

图论基础|417. 太平洋大西洋水流问题、827.最大人工岛、127. 单词接龙

目录 417. 太平洋大西洋水流问题 827.最大人工岛 127. 单词接龙 417. 太平洋大西洋水流问题 题目链接(opens new window) 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界&#xff0c;而 “大西洋” 处于大陆的右边界…

EDR下的线程安全

文章目录 前记进程断链回调执行纤程内存属性修改early birdMapping后记reference 前记 触发EDR远程线程扫描关键api&#xff1a;createprocess、createremotethread、void&#xff08;指针&#xff09;、createthread 为了更加的opsec&#xff0c;尽量采取别的方式执行恶意代…

C语言---------strlen的使用和模拟实现

字符串是以‘\0’作为结束标志&#xff0c;strlen函数的返回值是‘\0’前面的字符串的个数&#xff08;不包括‘\0’&#xff09; 注意 1&#xff0c;参数指向的字符串必须以‘\0’结束 2&#xff0c;函数的返回值必须以size_t,是无符号的 使用代码 ​ #include<stdio.…

数据库备份和恢复

前期准备 至少准备两台虚拟机完成Mysql的相关操作&#xff01; 在生产环境中&#xff0c;数据的安全性至关重要&#xff0c;任何数据的丢失都可能产生严重的后果。 造成数据丢失的原因&#xff1a; 程序错误人为操作错误运算错误磁盘故障&#xff1a; 解决措施&#xff1a;rai…

eric7安装报错

如果你遇到这样的问题&#xff1a; Sorry, please install QScintilla2 and its PyQt6 wrapper. Error: DLL load failed while importing Qsci: 找不到指定的程序。 如果你遇到这样的回答pip install QScintilla 如果你执行了这样的命令后&#xff0c;依旧报上面的错&#xf…

Word邮件合并

Word邮件合并功能可以解决在Word中批量填写内容的需求&#xff0c;当需要大量格式相同&#xff0c;只修改少数相关内容时&#xff0c;例如利用Word制作工资条&#xff0c;通知函&#xff0c;奖状等等&#xff0c;同时操作也非常简单灵活。下面通过例子来说明邮件合并的使用方法…

隧道技术和代理技术(四)SSHDNSICMPSMB上线通讯

目录 SSH&DNS&ICMP&SMB&上线通讯 DNS 隧道上线 DNS 隧道通讯 SSH 隧道通讯 SSH 隧道上线 SSH&DNS&ICMP&SMB&上线通讯 -连接方向&#xff1a;正向&反向&#xff08;基础课程有讲过&#xff09; -内网穿透&#xff1a;解决网络控制上…

《数据安全技术 数据分类分级规则》及典型行业标准指南要点提炼

数据分类分级发布新国标 千呼万唤&#xff0c;国家标准GB/T 43697-2024《数据安全技术 数据分类分级规则》于3月21日正式发布。作为全国网络安全标准化技术委员会更名后&#xff0c;发布的第一部以“数据安全技术”命名的国家标准&#xff0c;《数据安全技术 数据分类分级规则…

C++内存分布知识点复习

C内存分布&#xff08;只是用来自己复习&#xff0c;如果侵权了请联系&#xff0c;马上删除&#xff09; 看看自己是否了解 #define _CRT_SECURE_NO_WARNINGS #include<malloc.h> int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVa…

优秀人才必须具备的5个基本素质?

哈喽&#xff0c;大家好啊&#xff0c;我是雷工&#xff01; 张一鸣曾经在其微博上说过这么一句话&#xff1a; 选择越高级影响越大的人才&#xff0c;越要看一些基本素质。 那么优秀人才都具备哪些较好的基本素质呢&#xff1f; 或者说要具备哪些基本素质才有望成为高级人才&a…

[文生音乐]Suno AI:一句话,创作自己的音乐,全民创作人时代!

前言&#xff1a; 今年继AI生成文字&#xff08;Claude3&#xff09;、AI生成图片&#xff08;Midjourney&#xff09;、AI生成视频&#xff08;Sora&#xff09;之后&#xff0c;国外的AI公司又推出了一个劲爆的工具&#xff1a;Suno AI&#xff0c;通过一段简短的描述&#…

4G/5G视频记录仪_联发科MTK6765平台智能记录仪方案

视频记录仪主板采用了联发科MT6765芯片&#xff0c;该芯片采用12nm FinFET制程工艺&#xff0c;8*Cortex-A53架构&#xff0c;搭载安卓11.0/13.0系统&#xff0c;主频最高达2.3GHz&#xff0c;待机功耗可低至5ma&#xff0c;并具有快速数据传输能力。配备了2.4英寸高清触摸显示…

解决 cv2.imread读取带中文路径图片问题

http://t.csdnimg.cn/i8CXn 1.问题&#xff1a; # 中草药数据集样本可视化展示 import cv2 import matplotlib.pyplot as plt %matplotlib inline plt.title("heshouwu") plt.imshow(cv2.imread(r"D:\home\aistudio\data1\archive\train\何首乌\heshouwu_0001.…

huggingface的transformers训练bert

目录 理论 实践 理论 https://arxiv.org/abs/1810.04805 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是一种自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;由Google在2018年提出。它是基于Transformer模型的预训练方法…

机器学习(一)

经典定义: 利用经验改善系统自身的性能。 经典的机器学习过程: 基本术语: 数据集:训练集、测试集 示例、样例、样本 属性、特征:属性值 属性空间、样本空间、输入空间 特征向量 标记空间、输出空间 归纳偏好(偏置): 任何一个有效的机器学习算法必有其偏好 学习算法的…