【排序算法】冒泡排序(改进版)的思想分析与代码实现详解

简介: 【排序算法】冒泡排序(改进版)的思想分析与代码实现详解

冒泡排序算法分析

冒泡排序:Bubble sort,也叫做起泡排序,是一种交换性质的排序,基本思想是相邻两条记录进行比较,不符合规则就交换,符合规则不交换。冒泡排序的具体步骤描述如下

第一趟排序:

第1个元素与第2个元素比较,如果第1个元素大于第2个元素则交换,否则不进行任何操作;第2个元素与第3个元素比较,如果第2个元素大于第3个元素,则交换两个元素,否则不进行任何操作;重复上面操作,两两比较直到第n-1个元素和第n个元素比较完毕,第一趟冒泡结束。

经过第一趟排序后,整个数列中最大的数,通过冒泡冒到了数列的最后一个位置。

第二趟排序:

对前n-1个元素进行冒泡排序,即第1个位置与第2个位置比较,大于则交换,否则无操作;一直到第n-2个位置和第n-1个位置比较,大于则交换,否则无操作。通过第二趟冒泡排序,前n-1个元素中最大的数冒泡到n-1位置,也就是原始数组的倒数第二个位置(原始数组第二大的数)。

第n-1趟排序:

通过这种两两比较,经过n-1趟冒泡就可以将整个数组变为有序数组。并且从示意图中可以看出,红色的22本来就在黑色的22的前面,排序后红色22依然在黑色22前面,这说明冒泡排序不会改变相同数据原来的顺序,这说明,冒泡排序算法是稳定的。

冒泡算法的改进

有时候会有这样的情况,一组数据只有少数数据的顺序不对,而其他数据的顺序都是符合我们需要的顺序的(比如从小到大),比如下图中的情况

这组数据只有前两个位置不符合从小到大的顺序,而后面三个数据都已经符合从小到大的顺序了。此时,只需要一趟排序就可以完成整个数组的排序

但是,如果按照冒泡排序算法的全部流程,需要走完n-1趟排序才能完成,而第一趟冒泡排序之后的剩余流程其实是没有必要的。

这时,可以在冒泡排序中增加一个标志Flag,如果某一趟冒泡排序过程中,没有发生任何数据交换,则认为整个数组已经有序了,不需要在进行下一趟的冒泡排序,算法结束。比如上图中,在第一趟排序后整个数组已经从小到大排序完毕了,第二趟冒泡排序时,没有发生任何数据交换,则不再进行后续的冒泡,算法结束。这样就节省了很多不必要的时间,只需两趟冒泡就可以结束排序,而正常冒泡排序需要四趟冒泡。

改进版冒泡排序代码实现

1. //交换 i j 位置的元素
2. void swap(int array[], int i, int j)
3. {
4.  int temp = array[i];
5.  array[i] = array[j];
6.  array[j] = temp;
7. }
8. 
9. //冒泡排序
10. void bubble_sort(int array[], int num) //数组做函数参数会退化为指针,所以要传入数组元素个数
11. {
12.   int i = 0, j = 0, ChangeFlag = 1;
13.   for (i = 0; (i < num - 1) && (ChangeFlag == 1); i++) //总共多少趟排序 num - 1
14.   {
15.     ChangeFlag = 0; //默认假设无数据交换
16.     for (j = num - 1; j > i; j--)
17.     {
18.       if (array[j] < array[j - 1])
19.       {
20.         swap(array, j, j - 1);
21.         ChangeFlag = 1;
22.       }
23.     }
24.   }
25. }

冒泡排序的时候,从后往前冒或者从前往后冒都是可以的,也就是代码中的j从num-1开始或者从1开始都可以。

冒泡排序时间复杂度分析

时间复杂度是衡量一个排序算法好坏的重要标志,特别是在大量数据排序的时候。对于冒泡排序算法,最好的情况下,经过一趟排序就可以完成排序,总共需要n-1次两两比较的操作,此时复杂度为O(n);最坏的情况下,需要n-1趟排序才能完成整个数组的排序,此时需要的操作次数为,第一趟冒泡n-1次交换,第二趟冒泡n-2次交换,直到第n-1趟排序1次交换结束,共需要

次两两比较的操作,时间复杂度为O(n*n)。所以,冒泡排序的时间复杂度为

总结:冒泡排序是一种,稳定的,时间复杂度为的,简单的内排序。


相关文章
|
24天前
|
人工智能 算法 BI
第一周算法设计与分析 D : 两面包夹芝士
这篇文章介绍了解决算法问题"两面包夹芝士"的方法,通过找出两个数组中的最大最小值,计算这两个值之间的整数个数,包括特判不存在整数的情况。
|
15天前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
|
2天前
|
机器学习/深度学习 存储 人工智能
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
使用Python作为开发语言,基于文本数据集(一个积极的xls文本格式和一个消极的xls文本格式文件),使用Word2vec对文本进行处理。通过支持向量机SVM算法训练情绪分类模型。实现对文本消极情感和文本积极情感的识别。并基于Django框架开发网页平台实现对用户的可视化操作和数据存储。
11 0
文本情感识别分析系统Python+SVM分类算法+机器学习人工智能+计算机毕业设计
|
24天前
|
算法
算法设计与分析作业
这篇文章是关于算法设计与分析的作业,其中包含了两个算法实现:一个是使用分治算法实现的十进制大整数相乘(包括加法、减法和乘法函数),并进行了正确性和健壮性测试;另一个是使用快速排序思想实现的分治查找第K小元素的程序,并分析了其平均和最坏时间复杂度。
算法设计与分析作业
|
13天前
|
机器学习/深度学习 存储 算法
经典算法代码
这段代码展示了多个经典算法,包括:穷举法解决“百钱买百鸡”问题;递推法计算“猴子吃桃”问题;迭代法求解斐波那契数列及折纸高度超越珠峰的问题。同时,还提供了希尔排序算法实现及披萨票务订购系统和汉诺塔问题的链表存储解决方案。每部分通过具体案例解释了算法的应用场景与实现方法。
19 3
|
19天前
|
编解码 算法 图形学
同一路RTSP|RTMP流如何同时回调YUV和RGB数据实现渲染和算法分析
我们播放RTSP|RTMP流,如果需要同时做渲染和算法分析的话,特别是渲染在上层实现(比如Unity),算法是python这种情况,拉两路流,更耗费带宽和性能,拉一路流,同时回调YUV和RGB数据也可以,但是更灵活的是本文提到的按需转算法期望的RGB数据,然后做算法处理
|
24天前
|
人工智能 算法
第一周算法设计与分析:C : 200和整数对之间的情缘
这篇文章介绍了解决算法问题"200和整数对之间的情缘"的方法,通过统计数组中每个数模200的余数,并计算每个同余类中数的组合数来找出所有满足条件的整数对(i, j),使得\( A_i - A_j \)是200的整数倍。
|
24天前
|
人工智能 算法
第一周算法设计与分析 G : 排队援救
这篇文章介绍了解决算法问题"排队援救"的方法,通过使用队列和映射来模拟救援点的排队过程,并确定最终得到救援的人的顺序和编号。
|
24天前
|
算法 C++
第一周算法设计与分析 E : 构造回文串
这篇文章介绍了解决算法问题"构造回文串"的方法,即判断给定的整数N(视为字符串)是否可以通过在前面添加任意个0(或不添加)来构造一个回文串,并给出了相应的C++代码实现。
|
24天前
|
算法 C++
第一周算法设计与分析 H : 括号匹配
这篇文章介绍了解决算法问题"括号匹配"的方法,通过使用栈来检查给定字符串中的括号是否合法匹配,并提供了相应的C++代码实现。