【排序算法】详解冒泡排序及其多种优化稳定性分析

文章目录

  • 算法原理
  • 细节分析
  • 优化1
  • 优化2
  • 算法复杂度分析
  • 稳定性分析
  • 总结

算法原理

冒泡排序(Bubble Sort) 就是从序列中的第一个元素开始,依次对相邻的两个元素进行比较,如果前一个元素大于后一个元素则交换它们的位置。如果前一个元素小于或等于后一个元素,则不交换它们;然后每一轮目前的元素中最大的或最小的排到最上面,就像水中的泡泡冒出来一样,故取名为冒泡排序
在这里插入图片描述

说简单点,就是比较两个相邻的元素,将值大或值小的元素交换到右边

动图演示如下
在这里插入图片描述

细节分析

冒泡排序中如果元素有N个,那么完成N-1趟即可. 以升序为例,因为每一趟都会将最大的元素排在最右边,当进行完N-1趟之后,那么剩下的那一个元素一定就是最小的,也一定在最左边,所以在完成N-1趟之后,排序也最终完成.
在这里插入图片描述

代码实现:

void bubble_sort(int* arr, int sz) //数组传的指针,参数中还需传递一个数组大小
{int i = 0;//趟数for (i = 0; i < sz - 1; i++) //总共趟数只有n-1趟{int j = 0;for (j = 0; j < sz - 1 - i; j++) //每轮里面排的数要依次递减{if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}

优化1

比如下图两种情况,当代码原本就已经是顺序排好的,或者在中途的时候顺便已经排好,但是你仍将按照上面代码一步一步运行,效率就会大打折扣
所以我们可以设立一个标志位,来提示我们是否排序是否已经排好,不用再进行优化
在这里插入图片描述

所以我们可以在代码中设立一个标志位,来提示我们排序是否已经排好,不用再进行优化

void bubble_sort(int* arr, int sz) //数组传递一定是指针
{int i = 0;//趟数for (i = 0; i < sz - 1; i++){int k = 1;	//k就是一个标志位,在第一趟中如果k变成0了,就说明顺序是需要程序来排序的//如果k不变,还是等于1,则数据顺序本身就是好的,就直接breakfor (int j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;k = 0;}}if (k == 1){break;}}
}

优化2

然而这种优化只能做到某一次排好序的时候我们直接退出排序以达到这个节约时间的要求,所以我们可以继续优化,当一个数组接近有序时(特别是有一小部分已经有序)我们往往只需要在某一个小范围内排序即可,我们可以用一个标记来表示这个范围的下限,例如遇到下面的情况,第一趟时9之后就不会再改变了,所以后面我们就无需比较了
因此,我们可以用个下标index来限制
在这里插入图片描述

void bubble_sort(int* arr, int sz) 
{int i = 0;int index = sz - 1; //这个就是下标位int temporary_index = 0;//趟数for (i = 0; i < sz - 1; i++){int k = 1;	//标志位for (int j = 0; j < index; j++){if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;k = 0;temporary_index = j;//注意:由于我这里下标是j和j+1,所以这里的temporary_index = j//如果你下标是j和j-1,那么就要不一样了}}if (k == 1){break;}index = temporary_index;}
}

算法复杂度分析

时间复杂度:

普遍的冒泡排序算法的每一轮要遍历所有元素,轮转的次数和元素数量相当,所以时间复杂度是O(n^2).当然,最优的情况,列已经是顺序的,那么只要进行一次循环遍历一下,所以最优时间复杂度是O(n)

空间复杂度

冒泡排序没有额外开空间,所以空间复杂度为O(1)

稳定性分析

对于冒泡排序,拿升序举例,只有在前一个数大于后一个数的时候才会交换,小于或者等于都不会改变位置,所以当一前一后两个相同的数出现时,它们最终的相对顺序也不会改变所以冒泡排序是很稳定的排序

总结

传统的冒泡排序完全可以满足我们最基本的需求,但是也仅仅是最简单的需求,这种简单的两个for循环不加任何的判断语句的形式注定它只能是一种效率较低的算法。虽然能有优化去完善算法,但是总体来说,冒泡排序的效率低.当然冒泡排序也有自身的优点,比如稳定!并且,冒泡排序适合教学,冒泡排序也是许许多多程序员接触的第一个排序算法,所以教学意义重大.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据学习(6)-hive底层原理Mapreduce

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博>主哦&#x…

课题学习(七)----粘滑运动的动态算法

一、 粘滑运动的动态算法 在实际钻井过程中&#xff0c;钻柱会出现扭振和粘滑现象&#xff08;粘滑运动–B站视频连接&#xff09;&#xff0c;但并不总是呈现均匀旋转。如下图所示&#xff0c;提取一段地下数据时&#xff0c;转盘转速保持在100 r/min&#xff0c;钻头转速在0-…

Java设计模式之六大设计原则

为什么要学习设计模式&#xff1f; 要知道设计模式就是软件工程的方法经验的总结&#xff0c;也是可以认为是过去一段时间软件工程的一个最佳实践&#xff0c;要理解&#xff0c;不要死记硬背。掌握这些方法后&#xff0c;可以让你的程序获得以下好处&#xff1a; 代码重用性…

膝关节检测之1设计目标手势与物体交互的动画

原来只用unity自带的IK&#xff0c;发现背部不能动&#xff0c;且手和手指的移动和旋转试了好像没法通过animation实现&#xff08;加入关键帧并修改最终状态的数值后播放没有变化&#xff0c;确定最终关键帧的数值已经改了的&#xff09;。看资料&#xff0c;发现final IK&…

3D调研-摄像头

参考资料&#xff1a; 来源1&#xff1a;https://leap2.ultraleap.com/leap-motion-controller-2 来源2&#xff1a; Gemini 2 _双目结构光相机_机器人感知-奥比中光官网 来源3&#xff1a; 国内外深度相机大盘点&#xff0c;仅用于学习科普&#xff01;--机器视觉网 来源4&…

生产管理系统

车间的生产管理和控制的核心就是根据产品的制造工艺特点&#xff0c;考虑 到车 间内有限的资源&#xff0c;合理地调度生产&#xff0c;保证按时生产出质量合格的产 品。从面向 过程的观点来看&#xff0c;车间是产品的转换器&#xff0c;是制造过程组成的 集合。生产控制管 …

thinkphp6入门(9)-- 获取url路径中的应用名、控制器名、操作名

如果使用了多应用模式&#xff0c;可以通过下面的方法来获取当前应用 app(http)->getName(); 获取当前控制器 Request::controller(); 获取当前操作 Request::action(); 在中间件middleware中是无法获取控制器和操作的 需要将middleware的引入修改为 config 目录下的 ro…

token、cookie、session的对比以及Java实现

文章目录 token、cookie、session的实现原理、优缺点Java实现 token、cookie、session的实现原理、优缺点 Token、Cookie和Session是用于实现用户身份验证和状态管理的常见技术。它们各自有不同的实现原理、优点和缺点。 Token: 实现原理: Token是一种无状态的认证机制&#x…

乐器经营商城小程序的作用是什么

乐器产品覆盖的人群非常广&#xff0c;小学生、老年人都有不小需求&#xff0c;也因此市场中的从业商家相对较多&#xff0c;产品丰富可供消费者选购&#xff0c;然而在实际经营中&#xff0c;线上线下面临痛点不少。 通过【雨科】平台搭建乐器小程序商城&#xff0c;将所有产品…

CCF CSP认证 历年题目自练Day31

题目一 试题编号&#xff1a; 202206-1 试题名称&#xff1a; 归一化处理 时间限制&#xff1a; 500ms 内存限制&#xff1a; 512.0MB 题目背景 在机器学习中&#xff0c;对数据进行归一化处理是一种常用的技术。 将数据从各种各样分布调整为平均值为 0、方差为 1的标准分布&a…

Stm32_标准库_9_TIM

频率(HZ)是频率的基本单位1HZ是1s的倒数 STM32F103C8T6一般情况给定时器的内部时钟都是72MHz&#xff08;系统主频率&#xff09; TIM基本构成 计数器、预分频器、自动化重装 // 都是16位其中计数器、自动化重装&#xff0c;都是16位换算成10进制范围为[0, 655536] 时间 1 /…

【全网最细】谷歌小恐龙无敌代码它来了!

谷歌小恐龙是什么&#xff1f; 每次断网的时候&#xff0c;大家是不是都会玩一会&#xff0c;小恐龙快跑的游戏&#xff0c;或者在信息课上玩一玩&#xff0c;对不对&#xff1f; 还没玩过的小伙伴也不用担心&#xff0c;打开谷歌&#xff0c;输入这段网址&#xff1a;chrome…

C++智能指针(三)——unique_ptr初探

与共享指针shared_ptr用于共享对象的目的不同&#xff0c;unique_ptr是用于独享对象。 文章目录 1. unqiue_ptr的目的2. 使用 unique_ptr2.1 初始化 unique_ptr2.2 访问数据2.3 作为类的成员2.4 处理数组 3. 转移所有权3.1 简单语法3.2 函数间转移所有权3.2.1 转移至函数体内3.…

软件工程与计算总结(十一)人机交互设计

目录 ​编辑 一.引例 二.目标 三.人类因素 1.精神模型 2.差异性 四.计算机因素 1.可视化设计 2.常见界面类型 五.人机交互设计的交互性 1.导航 2.反馈 3.设计原则 六.设计过程 1.基本过程 2.界面原型化 一.引例 无论软件功能多么出色&#xff0c;亦或内部的构造…

LENOVO联想笔记本小新 Pro-14 2021AMD处理器ACH版(82MS)原厂Win10系统

下载链接&#xff1a;https://pan.baidu.com/s/1-KZ8Y9NmkS7nDXcMbhZLHw?pwdyrkx 系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、lenovo联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1…

Spring中的任务调度:探索@Scheduled和@Schedules注解的威力

Spring中的任务调度&#xff1a;探索Scheduled和Schedules注解的威力 前言第一部分&#xff1a;什么是定时任务第二部分&#xff1a;Scheduled和Schedules注解详解Scheduled注解常用的Scheduled注解属性&#xff1a; Schedules注解cron表达式详解 第三部分&#xff1a;高级用法…

深入篇【C++】总结智能指针的使用与应用意义(auto_ptr/unique_ptr/shared_ptr/weak_ptr)底层原理剖析+模拟实现

深入篇【C】总结智能指针的使用与应用意义&&(auto_ptr/unique_ptr/shared_ptr/weak_ptr&#xff09;底层原理剖析模拟实现 智能指针的出现智能指针的使用应用意义/存在问题智能指针原理剖析模拟实现auto_ptrunique_ptrshared_ptrweak_ptr 智能指针的出现 首先我们要理…

【个人记录】Ceph添加OSD

目标 1.已存在Ceph集群2.添加node1盘 /dev/nvme1n1 /dev/nvme2n1进入ceph集群 步骤 1.格式化磁盘 ceph-deploy disk zap node1 /dev/nvme1n1 /dev/nvme2n12.添加磁盘到osd ceph-deploy osd create --data /dev/nvme1n1 node1 ceph-deploy osd create --data /dev/nvme2n1 …

vscode ssh linux C++ 程序调试

vscode调试c++程序相比vs2022要复杂很多,vs2022可以"一键运行调试",vscode则需要自己配置。 ​vscode调试程序时,会在当前工作目录产生.vscode 目录, 该目录有两个重要文件launch.json和tasks.json, 下面介绍两种调试方法: 手动调试和自动调试。 手动调试 不管…

VUE树结构实现

实现效果: 数据库表结构如下: 要求:需要有parentId,id。parentId就是父记录的id 表数据要求:一定不要让一条记录的parentid和id相同 前端代码: 注意:el-table标签里面需要加上属性,才可以有下拉箭头的样式 <el-table v-loading="listLoading" :data