【C语言】深入理解冒泡排序算法(优化+详解)

简介: 【C语言】深入理解冒泡排序算法(优化+详解)

文章目录

什么叫冒泡排序

冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。

整个过程如同气泡冒起,因此被称作冒泡排序

通俗来说,也就是:

从第一个元素开始比较相邻的两个元素,如果第一个比第一个大或小,就互换它们的位置,这样先比较完一次,然后抛弃最大或最小的继续比较,直到排序完成。

冒泡排序的步骤:

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 每趟从第一对相邻元素开始,对每一对相邻元素作同样的工作,直到最后一对。
  • 针对所有的元素重复以上的步骤,除了已排序过的元素(每趟排序后的最后一个元素),直到没有任何一对数字需要比较。

动画演示:

此处引用网上一张比较经典的gif来展示冒泡排序的整个过程:


image.png

图解冒泡排序

有8个数组组成一个无序数列:5,8,6,3,9,2,1,7,希望从小到大排序。


image.png

按照冒泡排序的思想:把相邻的两个数字两两比较,当一个数字大于右侧相邻的数字时,交换他们的位置,当一个数字和他右侧的数字小于或等于的时候,不交换。

第一轮排序

  1. 首先让5和8进行交换,发现5比8小,因此元素位置不变;
  2. 接下来让8和6比较,发现8比6大,所以要交换8和6的位置;

image.png

  1. 继续让8和3比较,发现8比3要大,所以8和3 交换位置;

image.png

  1. 继续让8和9进行比较,发现8比9小,不用交换;
  2. 9和2进行比较,发现9比2大,进行交换;

image.png

  1. 继续让9和1进行比较,发现9比1大,所以交换9和1的位置;

image.png

  1. 最后,让9和7交换位置;

image.png

这样一来,元素9作为数列的最大元素,就已经排序好了

image.png

第二轮排序

  1. 首先让5和6比较,发现5比6小,位置不变;
  2. 接下来让6和3比较,发现6比3大,交换位置;

image.png

  1. 接下来让6和8比较,6比8小,位置不变;
  2. 8和2比较。8比2大,交换位置;

image.png

  1. 接下来让8和1比较,8比1大,因此交换位置;image.png
  2. 继续让8和7比较,发现8比7大,交换位置;

image.png

这样一来,第二轮排序已经好了

image.png

第三轮排序

按照以上步骤,可得第三轮排序:

image.png

第四轮排序

按照以上步骤,可得第四轮排序:

image.png

第五轮排序

按照以上步骤,可得第五轮排序:

image.png

第六轮排序

按照以上步骤,可得第六轮排序:

image.png

第七轮排序

按照以上步骤,可得第七轮排序,此时已经有序了:

image.png

第八轮排序

此时已经排序完成啦!

image.png

到此为止,所有的数字都是有序的了,冒泡排序是一种稳定排序,由于该排序算法的每一轮都要遍历所有的数字,一共要遍历n-1,所以时间复杂度为O(n^2)

那么我们如何区分排序算法是否稳定呢?

如果我们交换的时候,遇到两个相同的数字;

如果两个相同的数字在排序之后相对位置没有交换,那么就是稳定的排序,反之则是不稳定的排序。

代码实现

代码过程如下:

void bubble_sort(int* arr, int sz)
{
  int i = 0;
  int j = 0;
  for (i = 0; i < sz - 1; i++)
  {
    for (j = 0; j < sz - 1 - i; j++)
    {
      if (arr[j] > arr[j + 1])
      {
        int tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
      }
    }
  }
}
int main()
{
  int arr[10] = { 5, 8, 6, 3, 9, 2, 1, 7 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  bubble_sort(arr, sz);
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
 }

运行结果:

image.png

这个代码很简单,使用双循环的方式进行排序。

外部的循环控制所有回合,内部循环代表每一轮的冒泡处理,先进行元素比较,再进行元素交换。

代码优化

从上面的例子不难看出,我们可以对原来的冒泡排序进行优化。

我们仍然用上面呢个数列{ 5, 8, 6, 3, 9, 2, 1, 7 }为例子,从上面的图解可以看出在第六、第七、第八轮排序后,整个数列已经是有序的了,但是排序算法还是执行到了第八轮排序。

image.png

优化的思路是:如果能判断出数列已经是有序的了,并且做出标记,那么就不会执行多余的排序。

因此,我们可以进行一个优化,就是设置一个flags;

  • 如果在本轮排序中有元素进行交换,则说明数列无序,如果已经排序了那么设置为0;
  • 如果在本轮排序中,没有元素进行交换,则说明数列有序,那么设置为1。

现在我们来看看优化后的代码:

void bubble_sort(int* arr, int sz)
{
  int i = 0;
  int j = 0;
  int flags = 0;
  for (i = 0; i < sz - 1; i++)
  {
    for (j = 0; j < sz - 1 - i; j++)
    {
      if (arr[j] > arr[j + 1])
      {
        int tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
        flags = 1;//不是有序的,flags设置为1
      }
    }
    if (flags == 0)
      return;
  }
}
int main()
{
  int arr[8] = { 5, 8, 6, 3, 9, 2, 1, 7 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  int i = 0;
  printf("排序前: ");
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);
  }
  printf("\n");
  bubble_sort(arr, sz);
  printf("排序后: ");
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
 }

运行结果:

image.png

以上就是冒泡排序啦!

如有错误,欢迎指正话😊!

相关文章
|
3天前
|
机器学习/深度学习 数据采集 算法
基于GA遗传优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a实现时间序列预测,采用CNN-GRU-SAM网络结构。卷积层提取局部特征,GRU层处理长期依赖,自注意力机制捕捉全局特征。完整代码含中文注释和操作视频,运行效果无水印展示。算法通过数据归一化、种群初始化、适应度计算、个体更新等步骤优化网络参数,最终输出预测结果。适用于金融市场、气象预报等领域。
基于GA遗传优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
|
5天前
|
机器学习/深度学习 人工智能 算法
机器学习算法的优化与改进:提升模型性能的策略与方法
机器学习算法的优化与改进:提升模型性能的策略与方法
72 13
机器学习算法的优化与改进:提升模型性能的策略与方法
|
1天前
|
移动开发 算法 计算机视觉
基于分块贝叶斯非局部均值优化(OBNLM)的图像去噪算法matlab仿真
本项目基于分块贝叶斯非局部均值优化(OBNLM)算法实现图像去噪,使用MATLAB2022A进行仿真。通过调整块大小和窗口大小等参数,研究其对去噪效果的影响。OBNLM结合了经典NLM算法与贝叶斯统计理论,利用块匹配和概率模型优化相似块的加权融合,提高去噪效率和保真度。实验展示了不同参数设置下的去噪结果,验证了算法的有效性。
|
8天前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
|
11天前
|
机器学习/深度学习 数据采集 算法
基于PSO粒子群优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-GRU-SAM网络在时间序列预测中的应用。算法通过卷积层、GRU层、自注意力机制层提取特征,结合粒子群优化提升预测准确性。完整程序运行效果无水印,提供Matlab2022a版本代码,含详细中文注释和操作视频。适用于金融市场、气象预报等领域,有效处理非线性数据,提高预测稳定性和效率。
|
5天前
|
传感器 算法
基于GA遗传优化的WSN网络最优节点部署算法matlab仿真
本项目基于遗传算法(GA)优化无线传感器网络(WSN)的节点部署,旨在通过最少的节点数量实现最大覆盖。使用MATLAB2022A进行仿真,展示了不同初始节点数量(15、25、40)下的优化结果。核心程序实现了最佳解获取、节点部署绘制及适应度变化曲线展示。遗传算法通过初始化、选择、交叉和变异步骤,逐步优化节点位置配置,最终达到最优覆盖率。
|
5天前
|
算法
基于RRT优化算法的机械臂路径规划和避障matlab仿真
本课题基于RRT优化算法实现机械臂路径规划与避障。通过MATLAB2022a进行仿真,先利用RRT算法计算避障路径,再将路径平滑处理,并转换为机械臂的关节角度序列,确保机械臂在复杂环境中无碰撞移动。系统原理包括随机生成树结构探索空间、直线扩展与障碍物检测等步骤,最终实现高效路径规划。
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
71 10
|
1月前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
56 9
|
1月前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
45 8