当前位置: 首页 > news >正文

一篇讲透排序算法之插入排序and选择排序

1.插入排序

1.1算法思想

先将数组的第一个元素当作有序,让其后一个元素与其比较,如果比第一个元素小则互换位置,之后再将前两个元素当作有序的,让第三个元素与前两个元素倒着依次进行比较,如果第三个元素比第二个元素小的话,则交换位置,之后再比较第二个元素和第一个元素。

之后我们重复以上操作即可完成插入排序。

为了帮助大家理解,现在我们一步步完成这些操作。

1.2实现逻辑以及具体实现

首先,如果第二个元素小于第一个元素,则交换位置。

	if (a[1] < a[0]){int tmp = a[1];a[1] = a[0];a[0] = tmp;}

之后,我们就可以让第三个元素依次与前两个元素进行比较了。

在这里,我们要记录一下第二个元素的位置,否则我们不知道如何比较。

因此我们在这里定义一个end来记录第二个元素的位置。

int end = 1;
while (end)
{//如果第三个元素和第二个元素发生了交换//则比较第一个元素和新的第二个元素if (a[end + 1] < a[end]){int tmp = a[end + 1];a[end + 1] = a[end];a[end] = tmp;}//由于前end个元素已经有序,所以有一次没有进if就可以跳出循环了else{break;}end--;
}

现在我们就完成了单趟的循环,但我们需要比较多趟,而每趟的比较中不一样的变量就是end,每趟的比较end都会+1,因此我们在外层再写一个循环即可。

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

到这里我们已经完成了一次插入排序,最后我们只需要将这些内容放在函数定义当中即可彻底完成!

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

2.选择排序

2.1算法思想

先遍历一遍数组,找出最小的元素,然后与第一个元素交换位置。

之后从数组的第二个数开始,再遍历一遍数组,找出此次遍历中最小的数,与第二个数交换位置。

之后重复以上的操作即可完成任务。

使用上述的原理遍历数组,每次遍历都可以选出一个最小的数,放到对应的位置上面去。

2.2实现逻辑以及具体实现

现在我们来逐步实现这个排序算法

首先,我们应遍历数组,找出最小的元素。

int min=a[0];
for (int i = 0; i < n; i++)
{if (a[i] < min){int tmp = min;min = a[i];a[i] = tmp;}
}

我们这样写出现了一个问题,我们交换了min和a[i]的数值,但是a[0]处的数值并没有随着min的改变而改变,对此,我们应该怎么做呢?

这里我们可以将两数交换封装为一个函数,之后我们不再让min记录数值,而是记录下标即可。 

//假设最小的是下标为0处的元素
int min = 0;
for (int i = 0; i < n; i++)
{if (a[i] < a[min]){//交换下标,每次交换后,min中记录的则是较小数的下标//之后进入下一次循环,继续比较min = i;}
}
//比较完毕之后,交换数值即可
swap(&arr[min], &arr[0]);//这个函数自己写,我没贴上来。

现在我们已经找到了最小的数,而且已经将其放到了第一个位置上去。

现在我们只需要在外面再套一层循环,每次不断更新下标,即可完成选择排序。

for (int i = 0; i <n-1; i++)//一共需要比较n-1趟
{//此时i下标元素最小int min = i;for (int j = i+1; j < n; j++)//前i个有序,因此j=i+1,比较n个元素,因此j<n{//假设最小的是下标为j处的元素if (a[j] < a[min]){//交换下标,每次交换后,min中记录的则是较小数的下标//之后进入下一次循环,继续比较min = j;}}//比较完毕之后,交换数值即可swap(&arr[min], &arr[0]);
}

 我们将其封装在函数体内,即可完成一次排序。

void SelectSort(int* arr, int len)
{for (int i = 0; i < len - 1; i++){int min = i;for (int j = i + 1; j < len; j++){if (arr[j] < arr[min]){mini = j;}}swap(&arr[min], &arr[i]);}
}

2.3选择排序的优化

我们的选择排序还可以进行一下优化,我们可以一次循环同时找最小和最大的数据,只需要在每次比较时定义一个min,一个max,即可在一次循环中找到最小和最大的数据。

这里我们还是先完成第一趟排序,代码如下

int max = 0;
int min = 0;
for (int j =1; j < n; j++)//前i个有序,因此j=i+1,比较n个元素,因此j《n
{//假设最小的是下标为j处的元素if (a[j] < a[min]){//交换下标,每次交换后,min中记录的则是较小数的下标min = j;}if (a[j] > a[max]){//交换下标,每次交换后,min中记录的则是较大数的下标max = j;}
}
swap(&arr[min], &arr[0]);
swap(&arr[max], &arr[n-1]);

通过上面这段代码,我相信大家可以了解优化的原理了。

现在我们就可以着手于完成优化后的选择排序了。

由于我们在一个循环体内同时寻找最小值和最大值,并交换位置。

因此我们需要两个变量记录每次循环中最左边的值和最右边的值的下标,我们将其定义为begin和end。

当begin和end相遇时,我们的循环就结束了。这时我们的数组就有序了。

当begin>=end时,她们就有序了。因此我们的循环条件可以写为begin<end。

void SelectSort(int* arr, int len)
{int begin = 0;int end = len - 1;while (begin < end){//假设mini和maxi都是beginint mini = begin;int maxi = begin;for (int i = begin + 1; i <= end; i++){//找大if (arr[mini] > arr[i]){mini = i;}//找小if (arr[maxi] < arr[i]){maxi = i;}}swap(&arr[mini], &arr[begin]);swap(&arr[maxi], &arr[end]);begin++;end--;}}
}

到了这里,我们的选择排序已经基本完成了,

但是请大家思考一个问题: 

如果我们的begin和maxi重合的话,上面这段代码的执行逻辑是什么样的呢?

    如果begin和maxi重合,根据我们的代码逻辑,我们首先会交换mini和begin位置处的值。

此时我们的begin下标处的值已经更新成了mini处的值,而由于我们的maxi和begin是相同的,因此此时我们maxi下标处的值其实是mini处的值。

    文字表述可能比较抽象,我们现在将文字具象化为代码。

		swap(&arr[mini], &arr[begin]);swap(&arr[begin], &arr[end]);

那么应该怎么解决这个问题呢?很简单,因为我们的下标重合了,因此我们在进行完第一个交换之后更新一下maxi的值即可。

void SelectSort(int* arr, int len)
{int begin = 0;int end = len - 1;while (begin < end){//假设mini和maxi都是beginint mini = begin;int maxi = begin;for (int i = begin + 1; i <= end; i++){//找大if (arr[mini] > arr[i]){mini = i;}//找小if (arr[maxi] < arr[i]){maxi = i;}}swap(&arr[mini], &arr[begin]);//begin处的值和mini处的值交换了位置//因此现在mini处保存的值为最大值//我们将maxi更新为mini即可。if (begin == maxi){maxi = mini;}swap(&arr[maxi], &arr[end]);begin++;end--;}}
}

相关文章:

一篇讲透排序算法之插入排序and选择排序

1.插入排序 1.1算法思想 先将数组的第一个元素当作有序&#xff0c;让其后一个元素与其比较&#xff0c;如果比第一个元素小则互换位置&#xff0c;之后再将前两个元素当作有序的&#xff0c;让第三个元素与前两个元素倒着依次进行比较&#xff0c;如果第三个元素比第二个元素…...

CompletableFuture的主要用途是什么?

CompletableFuture 的主要用途是为复杂的异步编程模型提供一种更简单&#xff0c;更具可读性的方式。它主要用于以下几个方面&#xff1a; 非阻塞计算&#xff1a;CompletableFuture 为处理高延迟的计算任务提供了非阻塞的解决方案。你可以启动一个计算任务&#xff0c;而不需要…...

QtCreator,动态曲线实例

样式图&#xff1a; .ui 在sloem1.ui文件中&#xff0c;拖入一个label控件&#xff0c; 头文件.h #include "QtGui/QPainter.h" #include "QtCore/QTimer.h"protected:bool eventFilter(QObject *obj,QEvent *event);void labelPaint();public slots: /…...

Model-Based Pose Estimation for Rigid Objects(基于SIFT)

6D目标检测工程落地需求的小算力算法&#xff0c;本文具有借鉴意义&#xff0c;但对于特征点少的目标不太好用。 摘要 在多个实际应用中&#xff0c;经常会遇到确定图像中出现的物体姿态的问题。处理这一挑战的最有效策略是按照基于模型的范式进行&#xff0c;这涉及构建物体…...

STM32自己从零开始实操02:输入部分原理图

一、触摸按键 1.1指路 项目需求&#xff1a; 4个触摸按键&#xff0c;主控芯片 TTP224N-BSBN&#xff08;嘉立创&#xff0c;封装 TSSOP-16&#xff09;&#xff0c;接入到 STM32 的 PE0&#xff0c;PE1&#xff0c;PE2&#xff0c;PE3。 1.2走路 1.2.1数据手册重要信息提…...

JavaScript异步编程——03-Ajax传输json和XML的技术文档

JavaScript异步编程——03-Ajax传输json和XML的技术文档 目录 JavaScript异步编程——03-Ajax传输json和XML的技术文档 一、引言 二、Ajax简介 三、Ajax传输JSON数据 四、Ajax传输XML数据 五、总结 一、引言 在现代Web开发中&#xff0c;Ajax技术已经成为实现前后端数据交…...

移动端常用meta

在移动端开发中&#xff0c;<meta> 标签用于提供关于HTML文档的元数据&#xff0c;这些元数据不会显示在页面上&#xff0c;但可以被浏览器解析&#xff0c;用于控制页面的行为和外观。以下是一些在移动端开发中常用的 标签&#xff1a; 1. 视口设置 这是移动端开发中最…...

C++_C++11的学习

1. 统一的列表初始化 1.1&#xff5b;&#xff5d;初始化 在C98 中&#xff0c;标准就已经允许使用花括号 {} 对数组或者结构体元素进行统一的列表初始值设定。而到了C11&#xff0c;标准扩大了用大括号括起的列表 ( 初始化列表 )的使用范围&#xff0c;使其能适用于所有的内…...

RAC11G参数修改错误导致启库失败处理

问题描述 部署完一套3节点的11g RAC后&#xff0c;进行了内存的参数优化&#xff0c;优化时忘记了先备份参数文件&#xff0c;忘记了计算内存参数眼盲的复制粘贴执行内存优化sql导致优化后重启实例启动失败。艾&#xff0c;由于粗心自己给自己挖了个坑。 切记更改参数步骤&am…...

UE4打包Win64项目命令行

仅用于个人记录&#xff0c;写的粗糙&#xff0c;勿喷 BuildProject.bat 具体命名参数请参照UE引擎RunUAT源码&#xff08;Programs\AutomationTool下Program.cs&#xff09; 参数1&#xff1a;引擎安装路径 参数2&#xff1a;uproject路径 参数3&#xff1a;输出路径 参数…...

c语言bug汇总中篇5

40. 不关注代码风格一致性 代码风格一致性有助于提高代码的可读性和可维护性。如果团队成员使用不同的代码风格&#xff0c;会导致代码看起来杂乱无章&#xff0c;增加阅读和理解的成本。 为了保持代码风格的一致性&#xff0c;程序员应该&#xff1a; - 遵循团队或项目约定的…...

【linux】进程(一)

1. 冯诺依曼体系结构 计算机基本都遵循着冯诺依曼体系 我们使用的计算器是由一个个硬件构成的&#xff1a; 中央控制器&#xff08;CPU&#xff09; &#xff1a; 运算器 控制器 等输入设备 : 键盘&#xff0c;鼠标&#xff0c;网卡 等输出设备 : 显示器&#xff0c;网卡 等…...

手把手教你用Python轻松玩转SQL注入

一、浅谈SQL注入 SQL注入其实就是把SQL命令插入到WEB表单中提交或者输入一些页面请求的查询字符串&#xff0c;比如我们输网址&#xff0c;就是相当于这种操作&#xff0c;只不过我们不是在测试SQL注入漏洞&#xff0c;而仅仅只是为了输入后看到相应网页上的内容而已。一般方法…...

redis的几种部署模式及注意事项

Redis 可以以多种部署模式来满足不同的需求&#xff0c;其中一些常见的部署模式包括&#xff1a;单节点部署、主从复制部署、哨兵模式部署和集群部署。这些部署模式各有特点&#xff0c;适用于不同的场景和需求&#xff1a; 概念 单节点部署&#xff1a; 特点&#xff1a;单…...

使用Python生成一束玫瑰花

520到了&#xff0c;没时间买花&#xff1f;我们来生成一个电子的。 Python不仅是一种强大的编程语言&#xff0c;用于开发应用程序和分析数据&#xff0c;它也可以用来创造美丽的艺术作品。在这篇博客中&#xff0c;我们将探索如何使用Python生成一束玫瑰花的图像。 准备工作…...

紫光同创PGL22G开发板|盘古22K开发板,国产FPGA开发板,接口丰富

盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板&#xff0c;全面实现国产化方案&#xff0c;板载资源丰富&#xff0c;高容量、高带宽&#xff0c;外围接口丰富&#xff0c;不仅适用于高校教学&#xff0c;还可以用于实验项目、项目开发&#xff0c;一板…...

大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例, LLaMA-Factory是一个专门用于大语言模型微调的框架,它支持多种微调方法,如LoRA、QLoRA等,并提供了丰富的数据集和预训练模型,便于用户进行模型微调。通义千问…...

力扣爆刷第142天之二叉树五连刷(构造树、搜索树)

力扣爆刷第142天之二叉树五连刷&#xff08;构造树、搜索树&#xff09; 文章目录 力扣爆刷第142天之二叉树五连刷&#xff08;构造树、搜索树&#xff09;一、106. 从中序与后序遍历序列构造二叉树二、654. 最大二叉树三、617. 合并二叉树四、700. 二叉搜索树中的搜索五、98. …...

0407放大电路的频率响应

放大电路的频率响应 单时间常数RC电路的频率响应中频响应高频响应低频响应全频域响应 放大电路频率响应概述1. 直接耦合放大电路频域响应阻容耦合放大电路频域响应 4.7.1 单时间常数RC电路的频率响应 4.7.2 放大电路频率响应概述 4.7.3 单级共射极放大电路的频率响应 4.7.4 单级…...

数据分析必备:一步步教你如何用Pandas做数据分析(6)

1、Pandas 函数应用 Pandas 重建索引操作实例 要将您自己或其他库的函数应用于Pandas对象&#xff0c;您应该了解三个重要的方法。方法如下所述。要使用的适当方法取决于您的函数是希望对整个数据帧进行操作&#xff0c;还是行操作还是按列操作&#xff0c;还是按元素操作。 表…...

mRNA疫苗序列生物信息学分析:从密码子优化到免疫原性预测

1. 项目概述&#xff1a;解码两大mRNA疫苗的“核心蓝图”作为一名在生物信息学和基因组学领域摸爬滚打了十多年的“老码农”&#xff0c;我见过太多令人兴奋的数据集&#xff0c;但当我第一次在GitHub上看到这个名为“Assemblies-of-putative-SARS-CoV2-spike-encoding-mRNA-se…...

终极指南:10分钟掌握SPT-AKI存档编辑器完整使用教程

终极指南&#xff1a;10分钟掌握SPT-AKI存档编辑器完整使用教程 【免费下载链接】SPT-AKI-Profile-Editor Программа для редактирования профиля игрока на сервере SPT-AKI 项目地址: https://gitcode.com/gh_mirrors/sp/…...

HS2-HF_Patch终极指南:一键为Honey Select 2安装完整增强补丁

HS2-HF_Patch终极指南&#xff1a;一键为Honey Select 2安装完整增强补丁 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF_Patch是专为《Honey Select 2》…...

OpenCore Legacy Patcher终极指南:让老Mac免费运行最新macOS的完整教程

OpenCore Legacy Patcher终极指南&#xff1a;让老Mac免费运行最新macOS的完整教程 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher OpenCore Legacy Patcher是…...

一种用于并网光伏系统的创新型多层逆变器,以降低总谐波失真(THD)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 &#x1f381…...

3个维度深度解析:UABEA如何重塑Unity资源处理生态

3个维度深度解析&#xff1a;UABEA如何重塑Unity资源处理生态 【免费下载链接】UABEA c# uabe for newer versions of unity 项目地址: https://gitcode.com/gh_mirrors/ua/UABEA 在Unity游戏开发和资源处理的复杂生态中&#xff0c;开发者常常面临一个核心挑战&#xf…...

猫抓扩展完整指南:三步掌握浏览器视频嗅探与下载技巧

猫抓扩展完整指南&#xff1a;三步掌握浏览器视频嗅探与下载技巧 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓&#xff08;Cat-Catch&#…...

Copaw_dev:AI编程助手增强框架,提升代码生成与自动化开发效率

1. 项目概述&#xff1a;Copaw_dev 是什么&#xff0c;以及它为何值得关注如果你是一名开发者&#xff0c;尤其是对自动化、代码生成或者AI辅助编程感兴趣&#xff0c;那么“Copaw_dev”这个项目标题很可能已经引起了你的注意。乍一看&#xff0c;这个由“G-Divine”维护的项目…...

CircuitPython开发进阶:从库文档解读到内存优化与异步编程实战

1. 从“能用”到“精通”&#xff1a;为什么你需要深入理解CircuitPython库文档刚接触CircuitPython时&#xff0c;我们往往是从复制粘贴示例代码开始的。这没什么问题&#xff0c;快速让一个LED闪烁起来&#xff0c;或者让传感器读出数据&#xff0c;那种即时反馈的成就感是驱…...

3步强力清理:Pearcleaner让你轻松解决Mac应用残留文件问题

3步强力清理&#xff1a;Pearcleaner让你轻松解决Mac应用残留文件问题 【免费下载链接】Pearcleaner A free, source-available and fair-code licensed mac app cleaner 项目地址: https://gitcode.com/gh_mirrors/pe/Pearcleaner 你是否曾删除Mac应用后&#xff0c;发…...