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

排序算法C语言实现

算法概览

排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性适用场景
插入排序O(n²)O(n²)O(1)稳定小规模/基本有序
希尔排序O(n log n)O(n²)O(1)不稳定中等规模
冒泡排序O(n²)O(n²)O(1)稳定教学/小规模
堆排序O(n log n)O(n log n)O(1)不稳定大规模数据
选择排序O(n²)O(n²)O(1)不稳定小规模
快速排序O(n log n)O(n²)O(log n)不稳定通用场景
归并排序O(n log n)O(n log n)O(n)稳定大数据/外部排序
计数排序O(n+k)O(n+k)O(k)稳定整数/小范围数据

一、插入排序(Insertion Sort)

原理与特点

插入排序的工作方式类似于整理扑克牌:将未排序元素逐个插入到已排序序列的正确位置。它的优势在于处理小规模或基本有序数据时效率高。

void InsertSort(int* a, int n) {for(int i = 0; i < n - 1; i++) {int end = i;int tmp = a[end + 1];  // 待插入元素// 寻找插入位置并移动元素while (end >= 0) {if (a[end] > tmp) {a[end + 1] = a[end];  // 元素后移end--;} else break;}a[end + 1] = tmp;  // 插入元素}
}

特点分析

  • 稳定排序算法

  • 自适应:数据越有序,效率越高

  • 当n≤1000时效率优于复杂排序算法

二、希尔排序(Shell Sort)

原理与特点

希尔排序是插入排序的改进版,通过将数组分组进行插入排序,逐步减小分组间隔,最终实现整体有序。它突破了O(n²)的时间复杂度瓶颈。

void ShellSort(int* a, int n) {int gap = n;while(gap > 1) {gap = gap / 2;  // 动态缩小间隔for (int i = 0; i < n - gap; i++) {int end = i;int tmp = a[end + gap];// 组内插入排序while (end >= 0) {if (a[end] > tmp) {a[end + gap] = a[end];end -= gap;  // 跨步比较} else break;}a[end + gap] = tmp;}}
}

特点分析

  • 第一个突破O(n²)的排序算法

  • 间隔序列的选择影响效率(本例使用Knuth序列)

  • 中等规模数据排序的理想选择

三、冒泡排序

原理与特点

冒泡排序是最基础的排序算法之一,通过不断比较相邻元素并交换位置,使较大元素逐渐"浮"到数组末尾,如同气泡上升的过程。其名称就来源于这种元素移动的特性。

void BubbleSort(int* a, int n) {for(int j = 0; j < n; j++) {int exchange = 0;  // 交换标志位// 单趟冒泡:将最大元素移到末尾for (int i = 1; i < n - j; i++) {// 相邻元素比较交换if (a[i - 1] > a[i]) {Swap(&a[i - 1], &a[i]);exchange = 1;  // 标记发生交换}}// 提前终止优化:未发生交换说明已有序if (exchange == 0) break;}
}

关键优化点

  1. 提前终止机制

    • 通过exchange标志检测是否发生交换

    • 当某趟未发生交换时,说明数组已完全有序

    • 对基本有序数组效率显著提升

  2. 逐步缩小范围

    • 每完成一趟排序,待排序范围缩小一位

    • n - j确保已排序部分不再参与比较

四、堆排序(Heap Sort)

原理与特点

利用堆数据结构实现的排序算法,通过构建大顶堆,不断将堆顶元素(最大值)与末尾元素交换,然后调整剩余元素为堆。

// 向下调整堆
void AdjustDown(int* a, int n, int parent) {int child = parent * 2 + 1;while (child < n) {// 选择较大的子节点if (child + 1 < n && a[child] < a[child + 1]) child++;// 父子节点交换if (a[child] > a[parent]) {Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;} else break;}
}void HeapSort(int* a, int n) {// 从最后一个非叶节点建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--) AdjustDown(a, n, i);// 排序过程int end = n - 1;while (end > 0) {Swap(&a[0], &a[end]);  // 堆顶元素移到末尾AdjustDown(a, end, 0);  // 调整剩余堆end--;}
}

特点分析

  • 原地排序,空间复杂度O(1)

  • 适合处理超大规模数据

  • 常用于优先级队列实现

 

五、快速排序(Quick Sort)

原理与特点

采用分治策略的排序算法,通过选取基准值将数组划分为两个子数组,递归排序子数组。

 经典实现(双指针法)

void QuickSort(int* a, int left, int right) {if (left >= right) return;if (right - left + 1 < 10) {  // 小区间优化InsertSort(a + left, right - left + 1);} else {int midi = GetMidi(a, left, right);Swap(&a[left], &a[midi]);  // 基准值放最左int keyi = left;while (left < right) {while (left < right && a[right] >= a[keyi]) right--;while (left < right && a[left] <= a[keyi]) left++;Swap(&a[left], &a[right]);}Swap(&a[left], &a[keyi]);  // 基准值归位QuickSort(a, begin, left - 1);  // 递归左子数组QuickSort(a, left + 1, end);    // 递归右子数组}
}

 前后指针法(更高效)

void QuickSort2(int* a, int left, int right) {if (left >= right) return;int keyi = left;int prev = left, cur = left + 1;while (cur <= right) {if (a[cur] < a[keyi] && ++prev != cur)Swap(&a[prev], &a[cur]);cur++;}Swap(&a[keyi], &a[prev]);  // 基准值归位QuickSort2(a, left, prev - 1);QuickSort2(a, prev + 1, right);
}

六、归并排序(Merge Sort)

原理与特点

采用分治策略的稳定排序算法,将数组递归分割,然后合并有序子数组。本文提供递归和非递归两种实现。

void _MergeSort(int* a, int begin, int end, int* tmp) {if (begin >= end) return;int mid = (begin + end) / 2;// 递归分割_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid + 1, end, tmp);// 合并有序数组int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2) {tmp[i++] = a[begin1] <= a[begin2] ? a[begin1++] : a[begin2++];}// 处理剩余元素while (begin1 <= end1) tmp[i++] = a[begin1++];while (begin2 <= end2) tmp[i++] = a[begin2++];memcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}void MergeSort(int* a, int n) {int* tmp = malloc(sizeof(int) * n);_MergeSort(a, 0, n - 1, tmp);free(tmp);
}

特点分析

  • 稳定排序算法

  • 适合外部排序(大数据文件)

  • 链表排序的最佳选择

七、计数排序

void CountSort(int* a, int n) {// 确定数据范围int min = a[0], max = a[0];for (int i = 1; i < n; i++) {if (a[i] > max) max = a[i];if (a[i] < min) min = a[i];}int range = max - min + 1;// 创建计数数组int* count = malloc(sizeof(int) * range);memset(count, 0, sizeof(int) * range);// 统计元素频次for (int i = 0; i < n; i++) count[a[i] - min]++;// 回写排序结果int j = 0;for (int i = 0; i < range; i++) {while (count[i]--) a[j++] = i + min;}free(count);
}

适用场景

  • 数据范围为有限整数

  • 数据范围远小于数据量(k << n)

  • 需要稳定排序的场景

八、如何选择排序算法

  1. 小规模数据:插入排序

  2. 通用场景:快速排序(需随机化基准)

  3. 内存受限环境:堆排序

  4. 稳定排序需求:归并排序

  5. 已知数据范围:计数排序

  6. 链表排序:归并排序

  7. 外部排序:多路归并排序

相关文章:

排序算法C语言实现

算法概览 排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性适用场景插入排序O(n)O(n)O(1)稳定小规模/基本有序希尔排序O(n log n)O(n)O(1)不稳定中等规模冒泡排序O(n)O(n)O(1)稳定教学/小规模堆排序O(n log n)O(n log n)O(1)不稳定大规模数据选择排序O(n)O(n)O(1)不稳定…...

Python----目标检测(训练YOLOV8网络)

一、数据集标注 在已经采集的数据中&#xff0c;使用labelImg进行数据集标注&#xff0c;标注后的txt与原始 图像文件同名且在同一个文件夹&#xff08;data&#xff09;即可。 二、制作数据集 在data目录的同目录下&#xff0c;新建dataset目录&#xff0c;以存放制作好的YOLO…...

构建 MCP 服务器:第一部分 — 资源入门

什么是模型上下文协议? 模型上下文协议(MCP) 是Claude等大型语言模型 (LLM) 与外部数据和功能安全交互的标准化方式。您可以将其想象成一个平视显示器,或者 AI 的 USB 端口——它提供了一个通用接口,允许任何兼容 MCP 的 LLM 连接到您的数据和工具。 MCP 提供了一个集中式协…...

c# :this() 和 :base()区别

在 C# 中&#xff0c;:this() 和 :base() 都用于构造函数的重载和继承&#xff0c;但它们有不同的用途和上下文&#xff1a; 1. :this() 用途&#xff1a;用于调用当前类中的其他构造函数&#xff08;构造函数重载&#xff09;。场景&#xff1a;当你希望一个构造函数先执行另…...

使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十五讲)

这一期讲解lvgl中日历控件的基础使用&#xff0c;Calendar 部件是一个经典日历&#xff0c;它具有以下功能&#xff1a;• 通过一个7x7矩阵显示任何月份 • 显示日期名称 • 突出显示当前日期&#xff08;今天&#xff09; • 突出显示任何用户定义的日期 日历是一个可编辑的小…...

Vue中实现表格吸底滚动条效果,列太多时左右滚动条始终显示在页面中

1、安装 npm install el-table-horizontal-scroll 2、全局注册&#xff08;main.js&#xff09; import horizontalScroll from el-table-horizontal-scrollVue.use(horizontalScroll) 如下图&#xff0c;在main.js加上上面的代码 3、表格内引用 <el-table :data"…...

BeeWorks 协同办公能力:局域网内企业级协作的全场景重构

在企业数字化办公场景中&#xff0c;BeeWorks 以强大的协同办公能力&#xff0c;将局域网内的通讯、协作、业务流程整合为统一整体。作为专注于企业级局域网环境的协作平台&#xff0c;其不仅提供即时通讯基础功能&#xff0c;更通过办公工具集成、会议能力强化、业务系统对接等…...

Mermaid 绘图--以企业权限视图为例

文章目录 一、示例代码二、基础结构设计2.1 组织架构树2.2 权限视图设计 三、销售数据权限系统四、关键语法技巧汇总 一、示例代码 在企业管理系统开发中&#xff0c;清晰的权限视图设计至关重要。本文将分享如何使用 Mermaid 绘制直观的企业权限关系图&#xff0c;复制以下代…...

Redis(02)Win系统如何将Redis配置为开机自启的服务

一、引言 Redis 是一款高性能的键值对存储数据库&#xff0c;在众多项目中被广泛应用。在 Windows 环境下&#xff0c;为了让 Redis 能更稳定、便捷地运行&#xff0c;将其设置为系统服务并实现自动启动是很有必要的。这样一来&#xff0c;系统开机时 Redis 可自动加载&#xf…...

C++课设:高效的日程管理系统

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏介绍&#xff1a;《编程项目实战》 目录 一、C日程管理系统的时代价值1. 为什么选…...

功能测试、性能测试、安全测试详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、功能测试 1、单接口功能 手工测试中的单个业务模块&#xff0c;一般对应一个接口 例如&#xff1a; 登录业务------登录接口 加入购物车业务------加入购…...

提示词指南 --- 提示词的基本结构

提示词指南 --- 提示词的基本结构以及三种角色 什么是Prompt (提示词)Prompt的基本结构和三种角色提示词的三种核心“角色”&#xff08;Role&#xff09; 真实例子 什么是Prompt (提示词) 我们可以把“Prompt&#xff08;提示词&#xff09;”想象成和AI聊天时你说的“一句话…...

UI学习—cell的复用和自定义cell

前言 Nib是什么&#xff1f; Nib就是.xib文件&#xff1a;一个可视化的UI界面文件&#xff0c;它记录了一个UI组件&#xff08;例如一个表格单元格Cell&#xff09;的界面布局信息&#xff0c;可以在interfaceBuilder中创建 [UINib nibWithNibName:"CustomCell" b…...

20250605使用boot-repair来恢复WIN10和ubuntu22.04.6双系统的启动

rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair rootrootrootroot-X99-Turbo:~$ sudo add-apt-repository ppa:yannubuntu/boot-repair rootrootrootroot-X99-Turbo:~$ sudo apt-get install boot-repair 20250605使用boot-repair来恢复WIN10和ubuntu22.04.6…...

网络安全面试题目(无答案)

一、渗透测试与漏洞挖掘 如何绕过WAF进行SQL注入&#xff1f;列举三种技术并解释原理。 答案要点&#xff1a; 分块传输编码&#xff08;Chunked Transfer&#xff09;绕过正则检测 畸形HTTP参数&#xff08;如参数污染、Unicode编码&#xff09; 利用WAF规则盲区&#xff08…...

JavaScript性能优化实战

### 1. 减少全局变量 JavaScript里&#xff0c;全局变量就像一个大杂烩&#xff0c;啥都往里扔&#xff0c;很容易出问题&#xff0c;还会影响性能。为啥呢&#xff1f;因为全局变量会被所有函数共享&#xff0c;查找起来特别费劲&#xff0c;就像在一个大仓库里找东西&#xf…...

接口安全SOAPOpenAPIRESTful分类特征导入项目联动检测

1 、 API 分类特征 SOAP - WSDL OpenApi - Swagger RESTful - /v1/api/ 2 、 API 常见漏洞 OWASP API Security TOP 10 2023 3 、 API 检测流程 接口发现&#xff0c;遵循分类&#xff0c;依赖语言&#xff0c; V1/V2 多版本等 Method &#xff1a;请求方法 攻击方…...

视频汇聚平台EasyCVR“明厨亮灶”方案筑牢旅游景区餐饮安全品质防线

一、背景分析​ 1&#xff09;政策监管刚性需求​&#xff1a;国家食品安全战略及 2024年《关于深化智慧城市发展的指导意见》要求构建智慧餐饮场景&#xff0c;推动数字化监管。多地将“AI明厨亮灶”纳入十四五规划考核&#xff0c;要求餐饮单位操作可视化并具备风险预警能力…...

sql server如何创建表导入excel的数据

在 SQL Server 中&#xff0c;可以通过几种方式将 Excel 数据导入到数据库表中。下面是一个完整的流程&#xff0c;包括如何创建表&#xff0c;以及将 Excel 数据导入该表的方法&#xff1a; ✅ 方法一&#xff1a;使用 SQL Server Management Studio (SSMS) 的导入向导&#x…...

仓库自动化搬运:自动叉车与AGV选型要点及核心技术解析

自动叉车与AGV均可实现自主作业&#xff0c;无需人工驾驶即可搬运托盘化货物。然而&#xff0c;这两种解决方案存在一些关键差异。 自动叉车与AGV的对比 自动叉车与AGV是截然不同的车辆&#xff0c;其差异主要源于原始设计&#xff1a; 自动叉车是制造商对传统手动叉车进行改…...

java UDP 模板

UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的传输层协议&#xff0c;在 Java 中可以使用 UDP 进行网络编程。理论上没有服务器客户端之分&#xff0c;实际上算是有的&#xff0c;以下是 Java 中 UDP 编程的基本步骤和示例代码&#xff1a; 服务器端 创建…...

【亲测有效】Mybatis-Plus更新字段为null

Mybatis-Plus更新字段为null 遇到问题 Mybatis-Plus更新的默认行为如下: Mybatis-Plus默认如果某个传入参数的字段为null, 默认不更新这个字段, 例如有个Double类型的字段, 当前数据库数据为10, 然后传参时当前字段为null, 实际上Mybatis-Plus是不会覆盖该字段为null的, 仍然…...

NLP学习路线图(二十五):注意力机制

在自然语言处理领域&#xff0c;序列模型一直扮演着核心角色。从早期的循环神经网络&#xff08;RNN&#xff09;到如今一统天下的Transformer模型&#xff0c;注意力机制&#xff08;Attention Mechanism&#xff09; 的引入堪称一场革命。它彻底改变了模型处理序列信息的方式…...

05 APP 自动化- Appium 单点触控 多点触控

文章目录 一、单点触控查看指针的指针位置实现手势密码&#xff1a; 二、多点触控 一、单点触控 查看指针的指针位置 方便查看手势密码-九宫格每个点的坐标 实现手势密码&#xff1a; 执行手势操作&#xff1a; 按压起点 -> 移动到下一点 -> 依次移动 -> 释放&am…...

MyBatis-Plus LambdaQuery 高级用法:JSON 路径查询与条件拼接的全场景解析

目录 1. 查询 JSON 字段中的特定值 2. 动态查询 JSON 字段中的值 3. 查询 JSON 数组中的值 4. 查询 JSON 字段中的嵌套对象 5. 结合其他条件查询 JSON 字段 6. 使用类型处理器简化 JSON 查询 6.1 创建自定义 JSON 类型处理器 6.2 在实体类中指定自定义类型处理器 示例…...

[AI绘画]sd学习记录(一)软件安装以及文生图界面初识、提示词写法

目录 目录一、安装软件二、文生图各部分模块 1. 下载新模型 & 画出第一张图2. 提示词输入 2.1 设置2.2 扩展模型2.3 扩展模型权重调整2.4 其他提示词输入2.5 负向提示词2.6 生成参考 3. 采样方法4. 噪声调度器5. 迭代步数6. 提示词引导系数 一、安装软件 软件安装&…...

SpringBoot(八) --- SpringBoot原理

目录 一、配置优先级 二、Bean的管理 1. Bean的作用域 2. 第三方Bean 三、SpringBoot原理 1. 起步依赖 2. 自动配置 3. 自动配置原理分析 3.1 源码解析 3.2 Conditional 一、配置优先级 SpringBoot项目当中支持三类配置文件&#xff1a; application.properties a…...

SpringBoot自动化部署全攻略:CI/CD高效实践与避坑指南

SpringBoot自动化部署全攻略:CI/CD高效实践与避坑指南 🚀 一、现代化部署方案选型对比 1. 主流CI/CD工具对比 工具优势适用场景Jenkins插件丰富、可扩展性强复杂流水线、混合云环境GitHub Actions与GitHub深度集成、易用GitHub项目、中小团队GitLab CI/CD一体化平台、内置…...

idea json生成实体类

在IntelliJ IDEA中&#xff0c;可以通过安装GsonFormat或GsonFormatPlus插件快速生成Java实体类‌。具体操作流程包括安装插件、创建空类后使用快捷键调出生成界面&#xff0c;输入JSON数据即可自动生成对应字段和结构。‌‌ 一、操作流程与工具选择‌ ‌1、插件安装‌ 在ID…...

C# 类和继承(抽象成员)

抽象成员 抽象成员是指设计为被覆写的函数成员。抽象成员有以下特征。 必须是一个函数成员。也就是说&#xff0c;字段和常量不能为抽象成员。必须用abstract修饰符标记。不能有实现代码块。抽象成员的代码用分号表示。 例如&#xff0c;下面取自一个类定义的代码声明了两个抽…...