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语言——排序(冒泡,选择,插入)
基本概念 排序是对数据进行处理的常见操作,即将数据按某字段规律排列。字段是数据节点的一个属性,比如学生信息中的学号、分数等,可针对这些字段进行排序。同时,排序算法有稳定性之分,若两个待排序字段一致的数据在排序…...
如何本地部署DeepSeek
第一步:安装ollama https://ollama.com/download 打开官网,选择对应版本 第二步:选择合适的模型 https://ollama.com/ 模型名称中的 1.5B、7B、8B 等数字代表模型的参数量(Parameters),其中 B 是英文 B…...
Docker 部署 MySQL-5.7 单机版
一、镜像获取 # docker hub 镜像 docker pull farerboy/mysql:5.7 # 国内阿里镜像 docker pull registry.cn-hangzhou.aliyuncs.com/farerboy/mysql:5.7 以上两个镜像二选一即可 二、运行容器 docker run -dti --name mysql \n --privileged \n --cgroupns private \n --e…...
正则表达式--元字符-限定符(4)
正则的限定元字符 表示前边一个符号代表的内容出现多少次 1.* ------ 表示0~正无穷次 2. ------ 表示 1~正无穷次 3. ? ------ 表示 0~1次 4. {n} ------ 表示 限定 n 次, 不能多也不能少 5. {n,} ------ 表示 最少 n 次 6. {n,m} ------ 表示 最少 n 次, 最多 m 次 <!DO…...
【CMAEL多智能体框架】第一节 环境搭建及简单应用(构建一个鲜花选购智能体)
第一节 环境搭建 文章目录 第一节 环境搭建前言一、安装二、获取API1. 使用熟悉的API代理平台2.设置不使用明文存放API 三 、具体应用进阶任务 总结 前言 CAMEL Multi-Agent是一个开源的、灵活的框架,它提供了一套完整的工具和库,用于构建和模拟多智能体…...
网络工程师 (31)VLAN
前言 VLAN(Virtual Local Area Network)即虚拟局域网,是一种将物理局域网划分成多个逻辑上独立的虚拟网络的技术。 一、定义与特点 定义:VLAN是对连接到的第二层交换机端口的网络用户的逻辑分段,不受网络用户的物理位置…...
C++17 新特性解析
C++17 是 C++ 标准的一个重要更新,它在 C++11/14 的基础上引入了许多新特性,进一步简化了代码编写、提升了性能和类型安全性。以下是 C++17 的主要特性分类介绍: 一、语言核心改进 1. 结构化绑定(Structured Bindings) 允许将元组、结构体或数组的成员直接解包到变量中。…...
泛化、选择、分化
泛化是指记忆联系的“发散”,泛化兴奋的基础是模糊兴奋。记忆联系的“发散”有以下几种种情况: 1、联络区的一原始记忆柱群(A1)具有直接或间接与其它任意联络区的任意原始记忆柱群建立记忆联系的潜力。也就是说任何两个对象&…...
网络安全架构师怎么考 网络安全 架构
安全通信网络 随着现代技术的不断发展,等级保护对象通常通过网络实现资源共享和数据交互,当大量的设备连成网络后,网络安全成了最为关注的问题。按照“一个中心,三重防御”的纵深防御思想,边界外部通过广域网或城域网…...
Android系统分区概述和编译镜像包理解
1. 分区一:bootloader; 设备启动后,会先进入bootloader程序,这里会通过判断开机时的按键组合,选择启动到哪种模式。相当于电脑的bios 这里主要有Android系统、recovery模式(音量上键电源键)、f…...
【案例教程】无人机生态环境监测、图像处理与GIS数据分析综合实践技术应用
专题一、无人机航拍基本流程、航线规划与飞行实践 1.无人机行业应用概况 2.无人机遥感监测简介 3.无人机与传感器类型 4.无人机航线规划设计(谷歌地球软件的使用) 5.无人机飞行软件操作(DJI App设置实践视频) 6.无人机航拍一…...
depcheck检查node.js项目中未使用和缺失依赖的工具
depcheck检查node.js项目中未使用和缺失依赖的工具 一、安装二、使用方法 depcheck 是一个用于检查 Node.js 项目中未使用依赖项和缺失依赖项的工具。以下为你详细介绍它的相关信息、使用方法和作用。 主要作用: 1.发现未使用的依赖 在项目开发过程中,我们可能会安…...
在 C# 中,处理 Excel 和 PDF 文件的库有很多。以下是一些比较常用的选择
读取 Excel 文件的库 NPOI 用途:可以读取和写入 .xls 和 .xlsx 文件。特点:无需安装 Microsoft Office,支持简单的 Excel 操作,如格式化、公式、图表等。 EPPlus 用途:主要用于 .xlsx 格式(Excel 2007 及以…...
HTML之JavaScript函数声明
HTML之JavaScript函数声明 1. function 函数名(){}2. var 函数名 function(){}<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…...
【算法】动态规划专题⑪ —— 区间DP python
目录 引入进入正题回归经典总结 引入 区间动态规划(区间DP)适用于解决涉及区间最优化的经典问题,如石子合并、最长回文子序列等。 进入正题 石子合并 https://www.acwing.com/problem/content/284/ 有 N 堆石子排成一排,其编号为…...
现代C++多线程基础 -忆苦思甜pthread_mutex
c 老古董 文章目录 c 老古董pthread_mutex概念常用apipthread_mutex_initpthread_mutex_lockpthread_mutex_trylockpthread_mutex_unlockpthread_mutex_destroy 案例 pthread_mutex 概念 互斥锁 mutex是一种简单的加锁的方法来控制对共享资源的访问,mutex只有两种…...
玩转适配器模式
文章目录 解决方案现实的举例适用场景实现方式适配器模式优缺点优点:缺点:适配器模式可比上一篇的工厂模式好理解多了,工厂模式要具有抽象的思维。这个适配器模式,正如字面意思,就是要去适配某一件物品。 假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格…...
腾讯云大数据套件TBDS与阿里云大数据能力产品对比
前言 博主在接触大数据方向研究的时候是在2016年,那时候正是大数据概念非常火热的一个时间段,最著名的Google的3篇论文。Google FS、MapReduce、BigTable,奠定了大数据框架产品的基础。Google文件系统,计算框架和存储框架。往后所有的大数据产品和过程域无一不是在三个模块…...
Codeforces Round 1003 (Div. 4)(A~G题题解)
A. Skibidus and Amogu 思路:把字符串最后的us变成i就可以了,水题一个 #include <iostream> #include <string> int main() { int t; std::cin >> t; std::cin.ignore(); while (t--) { std::string W; std::getline(std::c…...
ubuntu使用防火墙开放和关闭指定端口
防火墙可以阻止或允许外部对特定端口的访问,Ubuntu 常用的防火墙管理工具是 ufw(Uncomplicated Firewall) ,如果在开发网络通信相关的内容时,要确保所需的端口是打开的,这样可以排除出题出现时的一个问题—…...
CP AUTOSAR标准之GPTDriver(AUTOSAR_SWS_GPTDriver)(更新中……)
1 简介和功能概述 该规范指定了AUTOSAR基础软件模块GPT驱动程序的功能、API和配置。 GPT驱动程序是微控制器抽象层(MCAL)的一部分。它初始化并控制微控制器的内部通用定时器(GPT)。 GPT驱动程序提供服务和配置参数 启动和停止硬件计时器获取计时器值控制时间触发的中断…...
mysql8.0使用PXC实现高可用
1.什么是 PXC PXC 是一套 MySQL 高可用集群解决方案,与传统的基于主从复制模式的集群架构相比 PXC 最突出特点就是解决了诟病已久的数据复制延迟问题,基本上可以达到实时同步。而且节点与节点之间,他们相互的关系是对等的。PXC 最关注的是数据…...
大数据学习之SparkStreaming、PB级百战出行网约车项目一
一.SparkStreaming 163.SparkStreaming概述 Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. Spark Streaming 是核心 Spark API 的扩展,支持实时数据…...
Ollama部署DeepSeek(windows or ubuntu)
Ollama(官网是https://ollama.com/)是一个专为在本地机器上便捷部署和运行大型语言模型(LLM)而设计的开源框架。它简化了大型语言模型的部署过程,提供了轻量级与可扩展的架构,使得研究人员、开发人员和爱好者能够更加方便地在本地…...
10.代码生成器-树表
1.导入部门表 2.配置生成信息页面 生成代码即可使用。...
2050年10月26日,星期四,芜湖
2050年10月26日,星期四,芜湖 清晨6:30,阳光透过智能调光窗帘缓缓洒进卧室,没有刺耳的闹钟,取而代之的是模拟自然光线和舒缓的江水声,这是林薇一天美好的开始。她的智能手环早已监测到她已进入浅睡眠状态&a…...
Python的那些事第十六篇:Python的网络爬虫技术
基于Python的网络爬虫技术研究与应用 摘要 随着互联网的飞速发展,网络爬虫技术在数据采集、信息挖掘等领域发挥着重要作用。本文详细介绍了Python环境下常用的网络爬虫技术,包括Requests库、BeautifulSoup库以及Scrapy框架。通过对这些工具的使用方法、…...
【AIGC】在VSCode中集成 DeepSeek(OPEN AI同理)
在 Visual Studio Code (VSCode) 中集成 AI 编程能力,可以通过安装和配置特定插件来实现。以下是如何通过 Continue 和 Cline 插件集成 DeepSeek: 一、集成 DeepSeek 获取 DeepSeek API 密钥:访问 DeepSeek 官方网站,注册并获取 …...
如何下载CentOS镜像文件
文章目录 如何下载CentOS镜像文件 如何下载CentOS镜像文件 直接前往阿里云官网下载即可。 阿里云官网地址:https://www.aliyun.com 进入官网后,鼠标停留在文档与社区位置,找到镜像站,点击进入即可。进入后,我们可以…...
大模型chagpt原理(持续更新)
20250210更新: 根据李宏毅课程可知,大模型chatgpt基本原理分为三步(每一步都是在做文字接龙,但训练资料不同) 一、依赖大量网上文章、维基百科等资料训练 对资料进行去重,劣质优质划分,过滤等…...
