【数据结构篇】排序1(插入排序与选择排序)

注:本文以排升序为例

常见的排序算法:

目录:

一 直接插入排序:

1.1 基本思想:

1.2 代码:

1.3 复杂度:

二 希尔排序(直接插入排序的优化):

2.1 基本思想:

2.2 代码:

2.3 复杂度:

三 直接选择排序:

3.1 基本思想:

3.2 代码:

3.3 复杂度:

四 堆排序:


一 直接插入排序:

1.1 基本思想:

直接插入排序是⼀种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到⼀个已经排好序的有序序列中,直到所有的记录插入完为止,得到⼀个新的有序序列。

  • 实际我们玩扑克牌时就用到了这一思想

动图:

https://i-blog.csdnimg.cn/direct/497745179f75471fb4fa306e4985a731.gif

解释:当插入第 i(i>=1) 个元素时,前面的 array[0],array[1],…,array[i-1] 已经排好序,此时⽤ array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进行比较,找到插入位置即将 array[i] 插入,原来位置上的元素顺序后移。

1.2 代码:

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

end:指向有序序列的最后一个数据:初始为0,末态为n-2

tmp:有序序列后的第一个待排序数据:初始为1,末态为n-1

以一次循环为例:
将tmp与end位置数据进行比较,

    若end处更大,将end位置数据移到end+1处,end--,继续让end-1处数据与tmp比较
    否则直接跳出循环,此时end+1位置为空,需要放入tmp

最坏的情况:当end为0处数据移到end为1处,此时end变为-1,需要跳出循环,并将tmp放到0处

1.3 复杂度:

元素集合越接近有序,直接插入排序算法的时间效率越高。
1.时间复杂度:O(N^2)

2.空间复杂度:O(1)

二 希尔排序(直接插入排序的优化):

在直接插入排序中我们发现,元素越无序,直接插入排序算法时间效率越低(因为比较次数越多)。特别是当数组为降序,我们要排升序,此时数组的相对无序程度达到了最大,时间复杂度也到了最大。所以D.L.Shell在1959年提出了希尔排序。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

        插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。

        但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

2.1 基本思想:

        希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定⼀个整数(通常是gap=n/3+1),把 待排序⽂件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap=gap/3+1得到下⼀个整数,再将数组分成各组,进行插入排序,当gap=1时,就相当于 直接插入排序。它是在直接插入排序算法的基础上进行改进⽽来的,综合来说它的效率肯定是要⾼于直接插入排序算法的。

以排序数组为例:

2.2 代码:

//希尔排序
//希尔排序时间复杂度大约为:O(n^1.3)
void ShellSort(int* arr, int n)
{int gap = n;//6while (gap > 1){gap = gap / 3 + 1;//保证最后一次gap一定为1for (int i = 0; i < n - gap; i++){int end = i;//n-gap-1int tmp = arr[end + gap];while (end >= 0){if (arr[end] > tmp){arr[end + gap] = arr[end];end -= gap;}else {break;}}arr[end + gap] = tmp;}}
}

直接插入排序法的改进,其在许多地方有相似之处:

    一次预排序
        从下标为0的元素开始,每隔gap-1个数据取数据分到一组,从取数据的方式我们可以得出以下结论:
            总共有gap组(0-(gap-1)的元素为每一组的头元素)
            每组有n/gap或n/gap+1个数据

        每一次排序我们排的是end和end+gap(即tmp)处的元素,保证每次排序都是在同一组内排
    end初始为0可得tmp初始为gap,tmp末态为n-1可得end末态为n-1-gap
    在一组内进行的是直接插入排序,只不过把距离从1换为gap,全部换一下就行了,思路是一样的,每次预排序结束后,让gap/3+1,加一保证最后一次排序gap为1,否则无法保证最后一次是直接插入排序

2.3 复杂度:

1.时间复杂度:最好O(N^1.3),最坏O(N^2)

2.空间复杂度:O(1)

三 直接选择排序:

3.1 基本思想:

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

动图:

https://i-blog.csdnimg.cn/direct/7541a586a0fd460ca2f219bd74f36bde.gif

3.2 代码:

void SelectSort(int* arr, int n)
{int begin = 0;int end = n - 1;while (begin < end){int 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;}}//mini begin//maxi end//避免maxi begini都在同一个位置,begin和mini交换之后,maxi数据变成了最小的数据if (maxi == begin){maxi = mini;}Swap(&arr[maxi], &arr[end]);Swap(&arr[mini], &arr[begin]);--end;++begin;}
}

1.每次在剩余序列中找最大的和最小的,最大的交换至后面,最小的交换至前面

2.

进入循环,mini找到1,maxi还是在9,此时我们将再将mini和begin交换,maxi与end交换,

end++,begin–跳出循环,排序完成仍然是931,出现了问题。所以需要

if (maxi == begin){maxi = mini;}

这样当我们将mini和begin交换完成后,maxi所指向的仍然是最大的数据,将其再与end交换

3.3 复杂度:

1.时间复杂度:O(N^2)

2.空间复杂度:O(1)

四 堆排序:

堆排序是指利⽤堆积树(堆)这种数据结构所设计的⼀种排序算法,它是选择排序的⼀ 种。它是通过堆来进⾏选择数据。需要注意的是排升序要建⼤堆,排降序建⼩堆。

在 【数据结构篇】顺序结构二叉树(堆)的堆排序已经讲过了此方法,这里就不赘述了。

以上就是【数据结构篇】排序1(插入排序与选择排序)的全部内容,欢迎指正~ 🌹🌹🌹

码文不易,还请多多关注支持,这是我持续创作的最大动力!

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

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

相关文章

Cursor日常配置指南

文章目录 整体说明一、简单介绍1.1、简介1.2、功能 二、日常配置2.1、Profiles 简介2.2、Cursor 配置2.2.1、通用设置&#xff08;General&#xff09;2.2.2、功能设置&#xff08;Features&#xff09;2.2.2.1、长上下文&#xff08;Large context&#xff09;2.2.2.2、代码索…

客户体验数据使用的三种视角——旅程视角

企业收集到大量的客户体验数据之后&#xff0c;应该如何应用&#xff1f;有哪些主要的使用场景和分析视角呢&#xff1f;接下来&#xff0c;体验家团队将通过三篇文章陆续介绍体验数据的三种应用场景&#xff0c;以帮助企业更有效地利用体验数据进行改进。 这三个场景分别是…

大语言模型怎么进行记忆的

大语言模型怎么进行记忆的 大语言模型(LLM)本身是无状态的,每次输入独立处理,但可通过以下方式实现对话记忆及长期记忆能力: 模型架构改进 显式记忆模块: 记忆网络(Memory Networks) :在模型里嵌入可读写的记忆单元,像键值存储 (Key - Value Memory)或动态记忆矩…

Spring Boot 与 RabbitMQ 的深度集成实践(三)

高级特性实现 消息持久化 在实际的生产环境中&#xff0c;消息的可靠性是至关重要的。消息持久化是确保 RabbitMQ 在发生故障或重启后&#xff0c;消息不会丢失的关键机制。它涉及到消息、队列和交换机的持久化配置。 首先&#xff0c;配置队列持久化。在创建队列时&#xf…

成功案例丨GEZE与Altair合作推动智能建筑系统开发

Altair 作为计算智能领域的全球领导者&#xff0c;将分别在北京、上海、成都、深圳举办 “AI驱动&#xff0c;仿真未来”Altair 区域技术交流会。届时将汇聚行业专家与先锋企业&#xff0c;共同探讨仿真智能化如何赋能工业创新&#xff0c;分享最新仿真与 AI 技术的应用实践。欢…

DDoS与CC攻击:谁才是服务器的终极威胁?

在网络安全领域&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;与CC&#xff08;Challenge Collapsar&#xff09;攻击是两种最常见的拒绝服务攻击方式。它们的目标都是通过消耗服务器资源&#xff0c;导致服务不可用&#xff0c;但攻击方式、威胁程度和防御策略存在显…

循环中使用el-form

循环中使用el-form 主要是校验问题 el-table 的数据 :data“ruleForm.tableData” :prop“‘tableData.’ $index ‘.name’” :rules“rules.name” <el-button type"primary" click"addNewData">新增项目</el-button><el-form :model&…

SAP学习笔记 - 开发13 - CAP 之 添加数据库支持(Sqlite)

上一章学习了CAP开发准备&#xff0c;添加Service。 SAP学习笔记 - 开发12 - CAP 之 开发准备&#xff0c;添加服务-CSDN博客 本章继续学习CAP开发 - 添加数据库支持&#xff08;Sqlite&#xff09;。 目录 1&#xff0c;数据库准备 - H2 内存数据库 - Sqlite数据库 a&…

【数据结构与算法】——图(三)——最小生成树

前言 本将介绍最小生成树以及普里姆算法&#xff08;Prim&#xff09;和克鲁斯卡尔&#xff08;Kruskal&#xff09; 本人其他博客&#xff1a;https://blog.csdn.net/2401_86940607 图的基本概念和存储结构&#xff1a;【数据结构与算法】——图&#xff08;一&#xff09; 源…

Flink运维要点

一、Flink 运维核心策略 1. 集群部署与监控 资源规划 按业务优先级分配资源&#xff1a;核心作业优先保障内存和 CPU&#xff0c;避免资源竞争。示例&#xff1a;为实时风控作业分配专用 TaskManager&#xff0c;配置 taskmanager.memory.process.size8g。 监控体系 集成 Prom…

面试点补充

目录 1. 搭建lnmp Linux 系统基础命令 nginx相关命令 MySQL 相关命令 PHP 相关命令 验证命令 下载并部署 Discuz! X3.4 论坛 到 Nginx 网站 2. 脑裂 2.1 脑裂的定义 2.2 脑裂产生的原因 1. 主备节点之间的心跳线中断 2. 优先级冲突 3. 系统或服务负载过高 2.3 如何…

天能股份SAP系统整合实战:如何用8个月实现零业务中断的集团化管理升级

目录 天能股份SAP系统整合案例&#xff1a;技术驱动集团化管理的破局之路 一、企业背景&#xff1a;新能源巨头的数字化挑战 二、项目难点&#xff1a;制造业的特殊攻坚战 1. 生产连续性刚性需求 2. 数据整合三重障碍 3. 资源限制下的技术突围 三、解决方案&#xff1a;S…

嵌入式学习笔记 - STM32独立看门狗IWDG与窗口看门狗WWDG的区别

下图说明了独立看门狗IWDG与窗口看门狗WWDG的区别: 从中可以看出&#xff1a; 一 复位 独立看门狗在计数器技术导0时复位&#xff0c; 窗口看门狗在计数器计数到0X40时复位。 二 喂狗 独立看门狗可以在计数器从预装载值降低到0过过程中的任意时间喂狗&#xff0c; 窗口看…

配电房值守难题终结者:EdgeView智能监控的7×24小时守护

在电力行业数字化转型的背景下&#xff0c;开关柜中的设备作为电能传输过程中的重要一环&#xff0c;其质量及运行状态直接关系到电网的安全性、可靠性、稳定性和抵抗事故的能力。 然而&#xff0c;在开关柜的调试部署与运行使用阶段&#xff0c;也常常会遇到设备标准不统一、…

B树与B+树全面解析

B树与B树全面解析 前言一、B 树的基本概念与结构特性1.1 B 树的定义1.2 B 树的结构特性1.3 B 树的节点结构示例 二、B 树的基本操作2.1 查找操作2.2 插入操作2.3 删除操作 三、B 树的基本概念与结构特性3.1 B 树的定义3.2 B 树的结构特性3.3 B 树的节点结构示例 四、B 树与…

如何使用VCS+XA加密verilog和spice网表

如果要交付verilog&#xff0c;但是需要对方进行VCS仿真&#xff0c;那么可以用以下方法&#xff1a; 一、基于编译指令的局部加密​ ​适用场景​&#xff1a;需精确控制加密范围&#xff08;如仅加密核心算法或敏感逻辑&#xff09;。 ​实现步骤​&#xff1a; ​代码标注…

策略模式-枚举实现

策略模式的实现方法有很多&#xff0c;可以通过策略类if,else实现。下面是用枚举类实现策略模式的方法。 定义一个枚举类&#xff0c;枚举类有抽象方法&#xff0c;每个枚举都实现抽象方法。这个策略&#xff0c;实现方法是工具类的很实现&#xff0c;代码简单好理解 枚举实现…

大数据hadoop小文件处理方案

Hadoop处理小文件问题的解决方案可分为存储优化、处理优化和架构优化三个维度,以下是综合技术方案及实施要点: 一、存储层优化方案 1.文件合并技术 离线合并:使用hadoop fs -getmerge命令将多个小文件合并为大文件并重新上传; MapReduce合并:开发专用MR…

线程调度与单例模式:wait、notify与懒汉模式解析

一.wait 和 notify&#xff08;等待 和 通知&#xff09; 引入 wait notify 就是为了能够从应用层面&#xff0c;干预到多个不同线程代码的执行顺序&#xff0c;可以让后执行的线程主动放弃被调度的机会&#xff0c;等先执行的线程完成后通知放弃调度的线程重新执行。 自助取…

ros运行包,Ubuntu20.04成功运行LIO-SAM

zz:~/lio_sam_ws$ source devel/setup.bash zz:~/lio_sam_ws$ roslaunch lio_sam run.launch 创建包链接&#xff1a; 链接1&#xff1a;Ubuntu20.04成功运行LIO-SAM_ubuntu20.04运行liosam-CSDN博客 链接2&#xff1a;ubuntu 20.04 ROS 编译和运行 lio-sam,并且导出PCD文件…