C语言——排序(冒泡,选择,插入)
基本概念
排序是对数据进行处理的常见操作,即将数据按某字段规律排列。字段是数据节点的一个属性,比如学生信息中的学号、分数等,可针对这些字段进行排序。同时,排序算法有稳定性之分,若两个待排序字段一致的数据在排序前后相对位置不变,则该排序算法是稳定的,否则不稳定。此外,根据数据量与内存的关系,还分为内排序(数据量小,可全部装入内存处理)和外排序(数据量大,需暂存外存,分批次读入内存处理)。
一、冒泡排序
(一)核心思想
冒泡排序基于相邻元素比较的思路。从头到尾让每两个相邻元素进行比较,若顺序符合排序要求则保持位置不变,若为逆序则交换位置。经过一轮比较,序列中具有 “极值”(最大值或最小值,取决于排序顺序)的数据会被挪至序列末端。
例如,对于数组[5, 3, 8, 6, 2]进行升序排序,从第一个元素开始,5 和 3 比较,因为 5 > 3,所以交换位置,数组变为[3, 5, 8, 6, 2];接着 5 和 8 比较,顺序不变;8 和 6 比较,交换位置,数组变为[3, 5, 6, 8, 2];8 和 2 比较,交换位置,第一轮比较结束后数组变为[3, 5, 6, 2, 8]。可以看到,最大的数 8 被移到了数组末尾。若序列中有n个数据,在最极端情况下,经过n - 1轮比较一定能将所有数据排序完毕。
(二)代码实现
// 冒泡排序,data为数组,len为数组长度
void bubbleSort(int* data, int len) {int i, j;for (i = 0; i < len - 1; i++) {int flag = 1; // 用于标记某一趟是否有元素交换,若没有则说明已排序完成for (j = 0; j < len - 1 - i; j++) {if (data[j] > data[j + 1]) { // 升序排序,若要降序改为data[j] < data[j + 1]int tmp;tmp = data[j];data[j] = data[j + 1];data[j + 1] = tmp;flag = 0; // 有元素交换,标记为0}}if (flag) { // 若某一趟没有元素交换,提前结束排序break;}}
}
(三)性能分析
冒泡排序的时间复杂度为 O(n^2),其中n是待排序数据的数量。这是因为在最坏情况下,需要进行n - 1轮比较,每轮比较的次数从n - 1逐渐减少到 1。空间复杂度为 O(1),因为它只需要几个临时变量来进行元素交换,不需要额外的大量空间。冒泡排序是一种稳定的排序算法,因为相同元素的相对顺序在排序过程中不会改变。
(四)示例图示
冒泡排序
以数组[5, 3, 8, 6, 2]的升序排序为例:
第一轮:
- 比较 5 和 3,交换,数组变为
[3, 5, 8, 6, 2] - 比较 5 和 8,顺序不变
- 比较 8 和 6,交换,数组变为
[3, 5, 6, 8, 2] - 比较 8 和 2,交换,数组变为
[3, 5, 6, 2, 8]
第二轮:
- 比较 3 和 5,顺序不变
- 比较 5 和 6,顺序不变
- 比较 6 和 2,交换,数组变为
[3, 5, 2, 6, 8]
第三轮:
- 比较 3 和 5,顺序不变
- 比较 5 和 2,交换,数组变为
[3, 2, 5, 6, 8]
第四轮:
- 比较 3 和 2,交换,数组变为
[2, 3, 5, 6, 8],排序完成。
二、选择排序
(一)核心思想
选择排序的思路是每一轮从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
例如,对于数组[5, 3, 8, 6, 2]进行升序排序,第一轮从数组中找到最小的数 2,与第一个数 5 交换位置,数组变为[2, 3, 8, 6, 5];第二轮从剩下的[3, 8, 6, 5]中找到最小的数 3,由于它已经在正确位置,无需交换;第三轮从[8, 6, 5]中找到最小的数 5,与 8 交换位置,数组变为[2, 3, 5, 6, 8];第四轮从[6, 8]中找到最小的数 6,由于它已经在正确位置,无需交换,此时数组已排序完成。
(二)代码实现
// 选择排序,data为数组,len为数组长度
void selectionSort(int* data, int len) {int i, j, minIndex;for (i = 0; i < len - 1; i++) {minIndex = i;for (j = i + 1; j < len; j++) {if (data[j] < data[minIndex]) { // 升序排序,若要降序改为data[j] > data[minIndex]minIndex = j;}}if (minIndex != i) {int tmp = data[i];data[i] = data[minIndex];data[minIndex] = tmp;}}
}
(三)性能分析
选择排序的时间复杂度同样为 O(n^2),因为无论数据初始状态如何,都需要进行n - 1轮选择和交换操作。空间复杂度为 O(1),只需要几个临时变量。选择排序是一种不稳定的排序算法,例如数组[5, 5, 3]进行升序排序时,两个 5 的相对顺序可能会改变。
(四)示例图示
选择排序
以数组[5, 3, 8, 6, 2]的升序排序为例:
第一轮:
找到最小的 2,与 5 交换,数组变为[2, 3, 8, 6, 5]
第二轮:
在剩下的[3, 8, 6, 5]中找到最小的 3,位置不变
第三轮:
在[8, 6, 5]中找到最小的 5,与 8 交换,数组变为[2, 3, 5, 6, 8]
第四轮:
在[6, 8]中找到最小的 6,位置不变,排序完成。
三、插入排序
(一)核心思想
插入排序假设前面已经有i个节点是有序的,那么从第i + 1个节点开始,插入到前面i个节点的合适位置中。由于第一个元素自身总是有序的,因此从第 2 个元素开始,不断插入前面的有序序列,直到全部排列完毕。
例如,对于数组[5, 3, 8, 6, 2]进行升序排序,初始时认为第一个元素 5 是有序的。然后取第二个元素 3,将其与 5 比较,因为 3 < 5,所以将 5 后移一位,把 3 插入到 5 原来的位置,数组变为[3, 5, 8, 6, 2];接着取第三个元素 8,由于 8 > 5,所以 8 的位置不变,数组仍为[3, 5, 8, 6, 2];再取第四个元素 6,将其依次与 8、5 比较,找到合适位置插入,数组变为[3, 5, 6, 8, 2];最后取第五个元素 2,将其依次与 8、6、5、3 比较,找到合适位置插入,数组变为[2, 3, 5, 6, 8]。
(二)代码实现
// 插入排序,data为数组,len为数组长度
void insertionSort(int* data, int len) {int i, j, tmp;for (i = 1; i < len; i++) {tmp = data[i];j = i - 1;while (j >= 0 && data[j] > tmp) { // 升序排序,若要降序改为data[j] < tmpdata[j + 1] = data[j];j--;}data[j + 1] = tmp;}
}
(三)性能分析
插入排序在最好情况下(数据已经有序)的时间复杂度为 O(n),因为只需要进行n - 1次比较,无需移动元素。在最坏情况下(数据逆序)的时间复杂度为 O(n^2),平均时间复杂度也为O(n^2)。空间复杂度为 O(1),只需要几个临时变量。插入排序是一种稳定的排序算法,因为在插入过程中,相同元素的相对顺序不会改变。
(四)示例图示
插入排序
以数组[5, 3, 8, 6, 2]的升序排序为例:
第一轮:
3 插入到 5 前面,数组变为[3, 5, 8, 6, 2]
第二轮:
8 位置不变,数组仍为[3, 5, 8, 6, 2]
第三轮:
6 插入到 8 前面,数组变为[3, 5, 6, 8, 2]
第四轮:
2 插入到最前面,数组变为[2, 3, 5, 6, 8],排序完成。
总结
冒泡排序、选择排序和插入排序都是简单的排序算法,它们的时间复杂度在最坏情况下都O(n^2),空间复杂度为O(1),适用于数据样本较小的场合。其中,冒泡排序和插入排序是稳定的排序算法,选择排序是不稳定的排序算法。在实际应用中,可根据数据特点和需求选择合适的排序算法。
相关文章:
C语言——排序(冒泡,选择,插入)
基本概念 排序是对数据进行处理的常见操作,即将数据按某字段规律排列。字段是数据节点的一个属性,比如学生信息中的学号、分数等,可针对这些字段进行排序。同时,排序算法有稳定性之分,若两个待排序字段一致的数据在排序…...
git如何下载指定版本
要使用Git下载指定版本,可以通过以下步骤进行操作: 1. 使用Git命令行下载指定版本: 1.1 首先,使用git clone命令克隆整个git库到本地。例如:git clone [库的URL]。这将下载最新的代码到本地。 1.2 进入克隆…...
数字电路-基础逻辑门实验
基础逻辑门是数字电路设计的核心元件,它们执行的是基本的逻辑运算。通过这些基本运算,可以构建出更为复杂的逻辑功能。常见的基础逻辑门包括与门(AND)、或门(OR)、非门(NOT)、异或门…...
新数据结构(9)——Java异常体系
异常的种类 程序本身通常无法主动捕获并处理错误(Error),因为这些错误通常表示系统级的严重问题,但程序可以捕获并处理异常(Excrption),而Error则被视为一种程序无法或不应尝试恢复的异常类型。…...
每日十题八股-补充材料-2025年2月15日
1.TCP是如何保证消息的顺序和可靠的? 写得超级好的文章 首先肯定是三次握手和四次挥手保证里通讯双方建立了正确有效的连接。 其次是校验和、序列号,ACK消息应答机制还有重传机制,保证了消息顺序和可靠。 同时配合拥塞机制和流量控制机制&am…...
使用 Python 爬虫获取微店快递费用 item_fee API 接口数据
在电商运营中,快递费用是影响商家利润和用户体验的重要因素之一。微店作为国内知名的电商平台,提供了丰富的 API 接口供开发者使用,其中也包括查询商品快递费用的接口。通过调用微店的 item_fee 接口,开发者可以获取指定商品的快递…...
通过用户名和密码登录服务器有哪些方法
通过用户名和密码登录到服务器的方式取决于你使用的工具和协议。以下是几种常见的方法: 1. 使用 SSH 登录到 Linux 服务器 你可以通过 SSH(Secure Shell)使用用户名和密码连接到远程服务器。通常,你会使用 ssh 命令来进行连接。…...
sort快排
当然可以!让我们通过类似的详细步骤来解释 快速排序(Quick Sort) 的原理和实现,就像之前解释 a &= (a - 1) 的原理一样。 快速排序(Quick Sort)原理 快速排序是一种高效的排序算法,其核心思想是分而治之。它通过选择一个“基准值”(pivot),将数组分为两部分: …...
用xml配置spring, bean标签有哪些属性?
用xml配置spring, bean标签有哪些属性? 在Spring框架中,使用XML配置文件时,<bean>标签用于定义一个Bean。以下是一些常用的<bean>标签属性: 1. class 描述:指定Bean的类名。示例:<bean id"myBe…...
纪念日倒数日项目的实现-【纪念时刻-时光集】
纪念日/倒数日项目的实现## 一个练手的小项目,uniappnodemysql七牛云。 在如今快节奏的生活里,大家都忙忙碌碌,那些具有特殊意义的日子一不小心就容易被遗忘。今天,想给各位分享一个“纪念日”项目。 【纪念时刻-时光集】 一…...
无人机不等同轴旋翼架构设计应用探究
“结果显示,对于不等组合,用户应将较小的螺旋桨置于上游以提高能效,但若追求最大推力,则两个相等的螺旋桨更为理想。” 在近期的研究《不等同轴旋翼性能特性探究》中,Max Miles和Stephen D. Prior博士深入探讨了不同螺…...
1-8 gitee码云的注册与使用
码云的网址:Gitee - 基于 Git 的代码托管和研发协作平台 这是一个国内的托管代码平台,速度要比国外的快 1.0 注册 如何注册码云? 查考文章:https://jingyan.baidu.com/article/425e69e6a8cad6ff14fc1615.html 2.0 使用 使用码云进…...
嵌入式硬件篇---OpenMV的硬件流和软件流
文章目录 前言一、硬件流控制(Hardware Flow Control)1. 基本原理RTSCTS 2. OpenMV中的实现• 硬件要求• 代码配置• 工作流程 二、软件流控制(Software Flow Control)1. 基本原理XONXOFF 2. OpenMV中的实现• 代码配置• 工作流…...
Word 里面嵌入DeepSeek
目录 一、问题描述 二、解决方法 三、代码 四、注意事项 五、总结 一、问题描述 如何在Word里面嵌入DeepSeek? 二、解决方法 1、新建文档,按 AltF11,进入VB界面。 2、选中文档,右键->插入->模块。 3、进入模块,粘入…...
聊聊 IP 地址和端口号的区别
在计算机网络中,两个基本概念对于理解设备如何通过网络进行通信至关重要。IP 地址和端口号是 TCP/IP 的典型特征,其定义如下:IP 地址是分配给连接到网络的每台机器的唯一地址,用于定位机器并与其通信。相反,端口号用于…...
rust学习一、入门之搭建简单开发环境
1、搭建开发环境(windows11) a.登录官网 一看就明白,此处略。 b.安装rustup 一看就明白,此处略。 c.安装 cargo script 或者 rust-script script cargo install cargo-script 完成后 注意:时间有一点点久。 测试 cargo s…...
浅聊MQ之Kafka与RabbitMQ简用
(前记:内容有点多,先看目录再挑着看。) Kafka与RabbitMQ的使用举例 Kafka的使用举例 安装与启动: 从Apache Kafka官网下载Kafka中间件的运行脚本。解压后,通过命令行启动Zookeeper(Kafka的运行…...
【原创】解决vue-element-plus-admin无法实现下拉框动态控制表单功能,动态显隐输入框
前言 目前使用vue-element-plus-admin想要做一个系统定时任务功能,可以选择不同的定时任务类型,比如使用cron表达式、周期执行、指定时间执行等。每种类型对应不同的输入框,需要动态显隐输入框才行,但是这个vue-element-plus-adm…...
SpringBoot开发——初步了解SpringBoot
文章目录 一、SpringBoot简介 1、什么是Spring Boot2、Spring Boot的优点3、Spring Boot功能 二、Spring与Spring Boot对比三、Spring Boot与Spring MVC四、Spring Boot体系结构五、Springboot Initializr 1、Spring Initializr2、Spring Initializr模块 一、SpringBoot简介…...
双轴伺服电机驱动控制器AGV、AMR专用双伺服电机驱动控制器解决方案
工业机器人数控机床XY机械手双轴机器人堆垛机专用双轴伺服电机驱动控制器48V 14ARMS带有STO功能,隔离高压CAN/RS485/USB通讯支持编码器和霍尔输入 双伺服电机驱动控制器TMCM2611功能介绍 集成2个伺服电机的控制和驱动于一体供电电压48V,驱动电流14A RM…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
