​【数据结构与算法】冒泡排序:简单易懂的排序算法解析

简介: ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析

一、引言

排序算法的简介

排序算法是计算机程序设计中的一种重要操作,其功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。

二、冒泡排序原理

🍃基本思想

通过重复地遍历待排序的序列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历序列的工作是重复地进行直到没有再需要交换,也就是说该序列已经排序完成。

🍃算法过程

  • 比较相邻元素:重复地走访需要排序的元素列表,依次比较两个相邻的元素。
  • 交换元素:如果顺序(如从大到小或从小到大)错误,就交换这两个元素的位置。
  • 重复进行:重复以上步骤,直到没有相邻的元素需要交换,则元素列表排序完成。

三、冒泡排序的实现

对于循环趟数和比较次数的控制,如图所示

以升序排序为例,每一趟排序可以将一个较大的值放在后面

循环趟数:

若数组大小为size,则最多需要进行size-1趟排序

(当排序size-1次之后,后面的size-1个元素已经被放在了正确的位置,剩下的一个元素自然不需要排序了)

比较次数:

若数组大小为size,则每一趟需要比较的次数是不同的

第一趟每两个元素都需要比较一次,总共是size-1次

第二趟排序,最后一个元素不需要比较,所以需要比较size-2次

……

总结成规律,每一趟需要比较的次数为size-1-(趟数-1)次

//冒泡排序
void BubbleSort1(DataType* a, int size)//升序排序
{
  for (int i = 0; i < size - 1; i++)//控制排序趟数
  {
    for (int j = 0; j < size - 1 - i; j++)//控制每次比较次数
    {
      if (a[j] > a[j + 1])//不满足升序就交换位置
      {
        DataType tmp = a[j];
        a[j] = a[j + 1];
        a[j + 1] = tmp;
      }
    }
  }
}
void BubbleSort2(DataType* a, int size)//降序排序
{
  for (int i = 0; i < size - 1; i++)//控制排序趟数
  {
    for (int j = 0; j < size - 1 - i; j++)//控制每次比较次数
    {
      if (a[j] < a[j + 1])//不满足降序就交换位置
      {
        DataType tmp = a[j];
        a[j] = a[j + 1];
        a[j + 1] = tmp;
      }
    }
  }
}

四、冒泡排序的优化

优化方法

设置一个标志位来判断是否发生了交换,从而提前结束排序

void BubbleSort(DataType* a, int size)//升序排序
{
  for (int i = 0; i < size - 1; i++)//控制排序趟数
  {
    int flag = 1;//标志位
    for (int j = 0; j < size - 1 - i; j++)//控制每次比较次数
    {
      if (a[j] > a[j + 1])//不满足升序就交换位置
      {
        flag = 0;//如果发生交换,改变标志位
        DataType tmp = a[j];
        a[j] = a[j + 1];
        a[j + 1] = tmp;
      }
    }
    if (flag == 1)//如果一趟排序没有发生交换,说明数据已经有序,可以提前结束
      break;
  }
}

五、冒泡排序的优缺点

  1. 优点简单易懂,容易实现,稳定性好(相等的元素在排序后不会改变相对顺序)。
  2. 缺点效率较低,尤其是当待排序序列已经有序或接近有序时,仍然需要执行完整的排序过程。

六、冒泡排序的应用场景

  1. 小型数据集:对于小型数据集,冒泡排序的简洁性和稳定性使其成为一个不错的选择。
  2. 教学示例:由于冒泡排序的直观性和易于理解性,它经常被用作教学示例来介绍排序算法的基本概念和原理。

总结

  • 冒泡排序,作为一种简单的排序算法,其核心思想是通过不断交换相邻两个元素的位置,使得每一轮迭代后,当前未排序部分的最大值(或最小值,取决于排序的方向)能够“冒”到序列的一端。尽管其时间复杂度在大数据集上并不理想,但冒泡排序在理解算法的基本思想和调试教学等方面仍具有不可忽视的价值。
  • 通过冒泡排序的学习,我们可以深入理解排序算法的基本步骤和原理,为后续学习更高效的排序算法(如快速排序、归并排序等)打下坚实的基础。同时,冒泡排序的直观性也使得它成为算法教学的常用工具,有助于初学者建立对算法设计和实现的直观认识。
  • 在实际应用中,我们通常会选择时间复杂度和空间复杂度更优的排序算法来处理大规模数据。但冒泡排序的简洁性和易理解性,使其在特定场合(如小规模数据排序、算法教学等)仍具有实用价值。
  • 冒泡排序作为一种经典的排序算法,不仅具有其独特的学术价值,也为后续学习更复杂的算法提供了有益的参考和启示。通过掌握冒泡排序的思想和实现方法,我们可以更好地理解排序算法的本质,为后续的学习和研究打下坚实的基础。
相关文章
|
9月前
|
搜索推荐 算法 Go
Go语言数组排序(冒泡排序法)—— 用最直观的方式掌握排序算法
本案例介绍使用冒泡排序对整数数组进行升序排序的实现方法,涵盖输入处理、错误检查与排序逻辑。通过代码演示和算法解析,帮助理解排序原理及Go语言切片操作,为学习更复杂排序算法打下基础。
|
9月前
|
搜索推荐
冒泡排序与其它排序算法比较
本内容比较了冒泡排序、选择排序和插入排序的特性。三者时间复杂度均为O(n²),但交换次数和稳定性不同。冒泡排序稳定,交换次数多,可优化至O(n);选择排序不稳定,交换次数少;插入排序交换次数最少,且二者均为稳定排序。对于有序数组,冒泡和插入可优化提升效率。
170 0
|
9月前
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
257 0
|
存储 搜索推荐 算法
算法系列之排序算法-堆排序
堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它的时间复杂度为 $O(nlogn)$,并且是一种原地排序算法(即不需要额外的存储空间)。堆排序的核心思想是利用堆的性质来维护一个最大堆或最小堆,然后逐步将堆顶元素(最大值或最小值)取出,放到数组的末尾,最终得到一个有序的数组。
392 8
算法系列之排序算法-堆排序
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
336 67
|
存储 机器学习/深度学习 算法
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
1133 29
|
存储 机器学习/深度学习 人工智能
C 408—《数据结构》易错考点200题(含解析)
408考研——《数据结构》精选易错考点200题(含解析)。
1541 27
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
搜索推荐
冒泡排序算法
【10月更文挑战第19天】冒泡排序是一种基础的排序算法,虽然在实际应用中可能不是最优的选择,但对于理解排序算法的基本原理和过程具有重要意义。
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。

热门文章

最新文章

推荐镜像

更多
  • DNS