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…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
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 解决方案&…...