两种交换排序算法--冒泡,快速
目录
1.冒泡排序原理
2.快速排序原理
3.冒泡代码实现
4.快速排序代码实现
1.冒泡排序原理
冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡一样“浮”到序列的顶部。
原理:
-
初始状态:我们从数组的第一个元素开始,比较相邻的两个元素。如果第一个元素大于第二个元素,就交换它们的位置;如果不大,则继续比较下一对元素。
-
第一轮排序:通过一轮比较后,最大的元素会被“冒泡”到数组的最后面。
-
继续排序:接着,我们对剩下的未排序部分继续进行类似的比较和交换,直到剩下的部分只有一个元素,意味着数组已经排序完成。
示例:
假设有一个数组 [5, 2, 9, 1, 5, 6],我们来演示一下冒泡排序的过程。
-
第一次遍历:
- 比较
5和2,交换,得到[2, 5, 9, 1, 5, 6] - 比较
5和9,不交换 - 比较
9和1,交换,得到[2, 5, 1, 9, 5, 6] - 比较
9和5,交换,得到[2, 5, 1, 5, 9, 6] - 比较
9和6,交换,得到[2, 5, 1, 5, 6, 9] - 第一轮结束,最大元素
9已经“冒泡”到最后。
- 比较
-
第二轮遍历:
- 比较
2和5,不交换 - 比较
5和1,交换,得到[2, 1, 5, 5, 6, 9] - 比较
5和5,不交换 - 比较
5和6,不交换 - 第二轮结束,最大元素
6已经排好位置。
- 比较
以此类推,直到所有元素都排好顺序。
时间复杂度:
- 最好的情况(已经有序):O(n)
- 最坏的情况(逆序):O(n²)
- 平均情况:O(n²)
虽然冒泡排序简单易懂,但由于其时间复杂度较高,通常在处理大数据时效率不高。
2.快速排序原理
快速排序(Quick Sort)是一种效率很高的排序算法,采用分治法(Divide and Conquer)的策略。它通过选择一个“基准”元素(pivot),然后将数组分成两部分:一部分比基准小,另一部分比基准大。接着递归地对这两部分分别进行快速排序,最终得到有序数组。
快速排序的基本原理:
-
选择基准元素:从数组中选择一个元素作为“基准”(pivot)。基准的选择方式可以有多种,比如选择第一个元素、最后一个元素、随机选择等。
-
分区操作:将数组重新排列,确保基准元素左边的元素都比它小,右边的元素都比它大。此时,基准元素已经排好位置了。
-
递归排序:对基准元素左边和右边的子数组分别进行快速排序。
-
终止条件:当子数组的长度为1或0时,递归终止,因为已经有序。
示例:
假设我们有一个数组 [10, 7, 8, 9, 1, 5],我们来演示一下快速排序的过程。我们选择最后一个元素 5 作为基准。
-
第一轮分区:
- 从左到右扫描数组,将小于基准元素的放左边,大于基准元素的放右边。最终,数组被分为
[1, 5, 8, 9, 7, 10],基准5排在了正确的位置。 - 此时,基准元素
5处于正确位置,左边的部分[1]和右边的部分[8, 9, 7, 10]需要继续排序。
- 从左到右扫描数组,将小于基准元素的放左边,大于基准元素的放右边。最终,数组被分为
-
递归对左部分排序:左边部分只有一个元素
[1],已经有序,不需要做任何操作。 -
递归对右部分排序:右边部分
[8, 9, 7, 10],选择基准元素10:- 分区后得到
[8, 9, 7, 10],基准元素10排在了正确的位置。 - 然后继续对
[8, 9, 7]排序。
- 分区后得到
-
继续递归分区:
- 对
[8, 9, 7]选择基准7,分区后得到[7, 9, 8]。 - 对
[9, 8]进行排序,最终得到[7, 8, 9]。
- 对
经过递归排序,最终得到有序的数组 [1, 5, 7, 8, 9, 10]。
快速排序的时间复杂度:
- 最优情况:当每次分区操作都能将数组均匀分成两部分时,时间复杂度是 O(n log n)。
- 最坏情况:当数组已经是升序或降序时,每次分区只能将一个元素排到正确位置,时间复杂度为 O(n²)。
- 平均情况:O(n log n),这是最常见的情况,且快速排序在大多数情况下都非常高效。
空间复杂度:
快速排序的空间复杂度通常为 O(log n),因为递归的深度最多为 log n(最好的情况下),但它是一个原地排序算法,不需要额外的存储空间。
优缺点:
- 优点:快速排序通常比其他 O(n log n) 排序算法(如归并排序)更高效,特别是对于大规模数据。
- 缺点:最坏情况下时间复杂度较高(O(n²)),但在实际应用中,通过优化基准元素的选择(比如三数取中法)可以有效避免这种情况。
3.冒泡代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//冒泡排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}//冒泡排序顺序表中的元素
void bubbleSort(ElemType* arr, int length) {for (int i = 0; i < length - 1; i++) { //外层循环,控制循环次数,最多n-1次bool flag = false; // 标记本趟排序是否发生交换for (int j = length - 1; j > i; j--) { //内层循环,从后往前通过比较冒出本趟最小元素if (arr[j - 1] > arr[j]) { //小于前一个元素则交换swap(arr[j - 1], arr[j]);flag = true;}}if (flag == false) { //本趟没有交换,说明有序,结束return;}}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值 bubbleSort(L.data, 10);//将顺序表进行排序printSqList(L);return 0;
}
4.快速排序代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>//快速排序typedef int ElemType;//顺序表
typedef struct SqList {ElemType* data;//指针,指向一块内存的起始地址int length;//存储动态数组的长度
}SqList;//顺序表初始化
void initSqList(SqList& L, int len) {L.length = len;L.data = (ElemType*)malloc(sizeof(ElemType) * L.length);//分配空间srand(time(NULL));//随机数生成for (int i = 0; i < L.length; i++){L.data[i] = rand() % 100;//随机生成数字存入顺序表,对100取余是为了规范存入的数据是0-99}
}//顺序表打印
void printSqList(SqList L) {for (int i = 0; i < L.length; i++){printf("%3d", L.data[i]);}printf("\n");
}void swap(ElemType& a, ElemType& b) {ElemType temp = a;a = b;b = temp;
}// 分割数组
int partition(ElemType* arr, int low, int high) {ElemType pivot = arr[low]; //将当前第一个元素作为枢轴元素,划分数组while (low < high) { //外层循环,low和high相遇时为枢轴元素的最终位置while (low < high && arr[high] >= pivot) //从后往前找到第一个小于枢轴的元素跳出循环--high;arr[low] = arr[high]; //将小于枢轴的元素移到左端while (low < high && arr[low] <= pivot) //从前往后找到第一个大于枢轴的元素跳出循环++low;arr[high] = arr[low]; //将大于枢轴的元素移到右端}arr[low] = pivot; //枢轴元素放入最终位置return low; //返回枢轴的最终位置
}// 快速排序顺序表中的元素
void quickSort(ElemType* arr, int low, int high) {if (low < high) { //递归结束条件//将表分为两个子表,枢轴元素是中间值,左子表小于它,右子表大于它int pivotpos = partition(arr, low, high); //枢轴元素已放入最终位置quickSort(arr, low, pivotpos - 1); //依次递归处理两个子表quickSort(arr, pivotpos + 1, high);}
}int main() {SqList L;//定义一个顺序表initSqList(L, 10);//初始化顺序表,分配10个空间printSqList(L);//打印顺序表中的值quickSort(L.data, 0, 9);//将顺序表进行排序printSqList(L);return 0;
}
相关文章:
两种交换排序算法--冒泡,快速
目录 1.冒泡排序原理 2.快速排序原理 3.冒泡代码实现 4.快速排序代码实现 1.冒泡排序原理 冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡…...
语音交友app系统源码功能及技术研发流程剖析
语音交友App的核心功能包括语音聊天、语音房间、社交互动等,开发流程涵盖需求分析、技术选型、前后端开发、实时通信集成、测试优化、部署上线及运营维护。 一、语音交友App的大概功能 1. 语音聊天 一对一聊天:用户可与好友进行私密语音通话。 群组语音…...
零基础Vue入门7——状态管理Pinia
本节重点: pinia是什么pinia怎么用 pinia是什么 vue中组件间的数据传递: app.config.globalProperties:能够被应用内所有组件实例访问到的全局属性的对象props:父传子用provide:父传后代用 想象下有咩有哪些数据存储…...
Bash (Bourne-Again Shell)、Zsh (Z Shell)
文章目录 1. 历史背景2. 主要区别3. 功能对比自动补全插件和主题路径扩展提示符定制 4. 性能5. 使用场景6. 如何切换 Shell7. 总结 以下是 Bash 和 Zsh 之间的主要区别,列成表格方便对比: 特性BashZsh默认Shell大多数Linux发行版默认ShellmacOS默认She…...
Android studio 创建aar包给Unity使用
1、aar 是什么? 和 Jar有什么区别 aar 和 jar包 都是压缩包,可以使用压缩软件打开 jar包 用于封装 Java 类及其相关资源 aar 文件是专门为 Android 平台设计的 ,可以包含Android的专有内容,比如AndroidManifest.xml 文件 &#…...
DeepSeek R1 简单指南:架构、训练、本地部署和硬件要求
DeepSeek 的 LLM 推理新方法 DeepSeek 推出了一种创新方法,通过强化学习 (RL) 来提高大型语言模型 (LLM) 的推理能力,其最新论文 DeepSeek-R1 对此进行了详细介绍。这项研究代表了我们如何通过纯强化学习来增强 LLM 解决复杂问题的能力,而无…...
图论常见算法
图论常见算法 算法prim算法Dijkstra算法 用途最小生成树(MST):最短路径:拓扑排序:关键路径: 算法用途适用条件时间复杂度Kruskal最小生成树无向图(稀疏图)O(E log E)Prim最小生成树无…...
MySQL三大日志详解
在MySQL数据库的运行过程中,三大关键日志——binlog、redo log和undo log,起着至关重要的作用。理解这三大日志,对于深入掌握MySQL的工作原理、数据恢复以及主从复制等操作有着极大的帮助。本文将详细剖析这三大日志的作用和工作机制。 Binl…...
【SQL 中的分组查询与联合查询详解】
文章目录 SQL 中的分组查询与联合查询详解 1. GROUP BY分组查询 1.1 语句格式1.2 示例说明 1.2.1 分别查询哥哥组和弟弟组的英语成绩总和1.2.2 查询哥哥组的所有成绩总和 2. 联合查询 2.1 内连接 2.1.1 语法格式2.1.2 执行过程 2.2 外连接 2.2.1 左外连接2.2.2 右外连接 2.3 …...
【实战篇】用 Cursor 独立开发并上线电商类 Android APP 全攻略
一、为啥要用 Cursor 开发电商类 Android APP 家人们,如今电商类 APP 随处可见,不管是买衣服、食品,还是电子产品,都能通过这些 APP 轻松搞定。要是能自己开发一款电商类 Android APP,那可太酷啦!但开发 APP 可不是一件容易的事,涉及到很多技术,像写代码、设计界面、处…...
quartus24.1版本子模块因时钟问题无法综合通过,FPGA过OOC问题复盘
因为只负责一个子模块,所以需要单独对该子模块进行综合和过OOC,这时候已经有一些加虚拟pin文件,敲命令让子模块能过OOC的方法。但这个方法的前提是先过综合,然后再敲命令让虚拟管脚命令成功,最终可以过OOC。 今天负责…...
零基础Vue入门6——Vue router
本节重点: 路由定义路由跳转 前面几节学习的都是单页面的功能(都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html),涉及到项目研发都是有很多页面的,这里就需要用到路由(vue route…...
使用 Let‘s Encrypt 和 OpenResty 实现域名转发与 SSL 配置
在搭建网站或服务时,确保域名的安全性和正确的流量转发是非常重要的。本文将介绍如何使用 Let’s Encrypt 获取免费的 SSL 证书,并将其配置到 OpenResty 中,同时实现特定的域名转发规则。这不仅可以提升网站的安全性,还能优化流量…...
Lambda 表达式
一、Lambda 表达式简介 Lambda 表达式是一种简洁的函数式编程方式,用于实现只有一个方法的接口(例如函数式接口)。 基本语法 (parameters) -> expression (parameters) -> { statements; } 参数:可以有零个或多个参数。…...
TCN时间卷积神经网络多变量多步光伏功率预测(Matlab)
代码下载:TCN时间卷积神经网络多变量多步光伏功率预测(Matlab) TCN时间卷积神经网络多变量多步光伏功率预测 一、引言 1.1、研究背景和意义 随着全球能源危机的加剧和环保意识的提升,可再生能源,尤其是太阳能&…...
【Elasticsearch】 Composite Aggregation 详解
1.什么是 Composite Aggregation? Composite Aggregation 是 Elasticsearch 中的一种特殊聚合方式,适用于需要分页展示的聚合结果。它与传统的聚合方式不同,采用了基于游标的分页模型。这种聚合方式可以高效地处理多级聚合中的所有桶&#x…...
如何通过 Logstash 将数据采集到 Elasticsearch
作者:来自 Elastic Andre Luiz 将 Logstash 与 Elasticsearch 集成以实现高效的数据提取、索引和搜索的分步指南。 什么是 Logstash? Logstash 是一种广泛使用的 Elastic Stack 工具,用于实时处理大量日志数据。它充当高效的数据管道&#x…...
mysql的cpu使用率100%问题排查
背景 线上mysql服务器经常性出现cpu使用率100%的告警, 因此整理一下排查该问题的常规流程。 1. 确认CPU占用来源 检查系统进程 使用 top 或 htop 命令,确认是否是 mysqld 进程导致CPU满载:top -c -p $(pgrep mysqld)2. 实时分析MySQL活动 …...
centos虚拟机迁移没有ip的问题
故事背景,我们的centos虚拟机本来是好好的,但是拷贝到其他电脑上就不能分配ip,我个人觉得这个vmware他们软件应该搞定这个啊,因为这个问题是每次都会出现的。 网络选桥接 网络启动失败 service network restart Restarting netw…...
接入 deepseek 实现AI智能问诊
1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
小智AI+MCP
什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析:AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github:https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…...
