news 2026/4/2 9:46:08

深入浅出冒泡排序:原理、实现与优化(附C++代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入浅出冒泡排序:原理、实现与优化(附C++代码)

深入浅出冒泡排序:原理、实现与优化(附C++代码)

大家好!今天我们来聊聊排序算法里最基础也最经典的一种——冒泡排序。它的核心思想简单易懂,非常适合排序算法的入门学习。这篇文章会从原理拆解、过程演示、代码实现,再到优化方向,一步步带大家吃透冒泡排序,最后附上可直接运行的C++代码,方便大家实操练习。

一、什么是冒泡排序?

冒泡排序(Bubble Sort)是一种简单的交换排序算法,它的核心思路是:重复遍历要排序的数组,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。

为什么叫“冒泡”呢?因为在排序过程中,较大的元素会像水中的气泡一样,逐渐“上浮”到数组的末尾(或者较小的元素“下沉”到数组开头),每一轮遍历都会确定一个未排序部分的最大(或最小)元素的最终位置。

二、冒泡排序的核心原理与过程演示

1. 核心原理

冒泡排序的本质是通过相邻元素的多次比较与交换,将无序元素逐步“筛选”到正确位置。其基本步骤如下:

  • 从数组的第一个元素开始,依次比较相邻的两个元素(第i个和第i+1个);

  • 如果前者大于后者(升序排序),则交换这两个元素的位置;

  • 继续向后比较下一对相邻元素,直到遍历到数组的末尾;

  • 完成一轮遍历后,数组中最大的元素会被“冒泡”到数组的最后一位(这一位已排序完成,后续遍历无需再考虑);

  • 重复上述过程,每轮遍历排除已排序的末尾元素,直到整个数组有序。

2. 过程演示(以数组 [5, 3, 8, 4, 2] 升序排序为例)

初始数组:[5, 3, 8, 4, 2]

第1轮遍历(未排序范围:0~4):

  • 比较 5 和 3:5>3,交换 → [3, 5, 8, 4, 2]

  • 比较 5 和 8:5<8,不交换 → [3, 5, 8, 4, 2]

  • 比较 8 和 4:8>4,交换 → [3, 5, 4, 8, 2]

  • 比较 8 和 2:8>2,交换 → [3, 5, 4, 2, 8]

  • 结果:最大元素 8 冒泡到末尾,有序部分:[8]

第2轮遍历(未排序范围:0~3):

  • 比较 3 和 5:3<5,不交换 → [3, 5, 4, 2, 8]

  • 比较 5 和 4:5>4,交换 → [3, 4, 5, 2, 8]

  • 比较 5 和 2:5>2,交换 → [3, 4, 2, 5, 8]

  • 结果:第二大元素 5 冒泡到倒数第二位,有序部分:[5, 8]

第3轮遍历(未排序范围:0~2):

  • 比较 3 和 4:3<4,不交换 → [3, 4, 2, 5, 8]

  • 比较 4 和 2:4>2,交换 → [3, 2, 4, 5, 8]

  • 结果:第三大元素 4 冒泡到倒数第三位,有序部分:[4, 5, 8]

第4轮遍历(未排序范围:0~1):

  • 比较 3 和 2:3>2,交换 → [2, 3, 4, 5, 8]

  • 结果:第四大元素 3 冒泡到倒数第四位,有序部分:[3, 4, 5, 8]

此时数组已完全有序,无需进行第5轮遍历。最终排序结果:[2, 3, 4, 5, 8]

三、冒泡排序的C++代码实现

1. 基础版本(未优化)

根据上述原理,我们可以直接写出基础版本的冒泡排序代码。核心是双重循环:外层循环控制遍历轮数(最多n-1轮,n为数组长度),内层循环控制每轮的相邻元素比较与交换。

#include<iostream>#include<vector>usingnamespacestd;// 冒泡排序基础版本(升序)voidbubbleSortBasic(vector<int>&arr){intn=arr.size();// 外层循环:控制排序轮数,最多需要n-1轮for(inti=0;i<n-1;++i){// 内层循环:每轮比较相邻元素,排除已排序的末尾i个元素for(intj=0;j<n-1-i;++j){// 如果前一个元素大于后一个,交换if(arr[j]>arr[j+1]){swap(arr[j],arr[j+1]);// C++标准库swap函数,交换两个元素}}}}// 打印数组voidprintArray(constvector<int>&arr){for(intnum:arr){cout<<num<<" ";}cout<<endl;}intmain(){vector<int>arr={5,3,8,4,2};cout<<"排序前:";printArray(arr);bubbleSortBasic(arr);cout<<"排序后:";printArray(arr);return0;}

2. 优化版本(添加有序标记)

基础版本存在一个问题:如果数组在第k轮(k < n-1)就已经完全有序,后续的轮数仍然会继续执行,造成不必要的性能浪费。

优化思路:添加一个有序标记(flag)。每轮遍历开始前将flag设为true,若本轮发生了元素交换,则将flag设为false;如果某轮遍历结束后flag仍为true,说明数组已完全有序,直接退出循环即可。

#include<iostream>#include<vector>usingnamespacestd;// 冒泡排序优化版本(添加有序标记)voidbubbleSortOptimized(vector<int>&arr){intn=arr.size();boolisSorted;// 标记数组是否已有序for(inti=0;i<n-1;++i){isSorted=true;// 初始假设本轮遍历后数组有序for(intj=0;j<n-1-i;++j){if(arr[j]>arr[j+1]){swap(arr[j],arr[j+1]);isSorted=false;// 发生交换,说明数组尚未有序}}if(isSorted){break;// 若未发生交换,直接退出循环,无需后续遍历}}}// 打印数组voidprintArray(constvector<int>&arr){for(intnum:arr){cout<<num<<" ";}cout<<endl;}intmain(){vector<int>arr={5,3,8,4,2};cout<<"排序前:";printArray(arr);bubbleSortOptimized(arr);cout<<"排序后:";printArray(arr);return0;}

3. 代码运行结果

上述两个版本的代码运行后,输出结果均为:

排序前:5 3 8 4 2 排序后:2 3 4 5 8

四、冒泡排序的性能分析

1. 时间复杂度

  • 最坏情况:数组完全逆序。此时每轮都需要进行n-1-i次比较和交换,总比较次数为 (n-1) + (n-2) + … + 1 = n(n-1)/2,时间复杂度为 O(n²);

  • 最好情况:数组已完全有序(优化版本)。此时只需进行1轮遍历(n-1次比较,0次交换),时间复杂度为 O(n);

  • 平均情况:时间复杂度为 O(n²)。

2. 空间复杂度

冒泡排序是原地排序算法,排序过程中只需要额外的常数级空间(用于存储循环变量、有序标记等),空间复杂度为 O(1)。

3. 稳定性

冒泡排序是稳定排序算法。因为只有当相邻元素严格大于(或小于)时才会交换,相等元素不会发生交换,因此它们的相对位置不会改变。

五、冒泡排序的适用场景

由于冒泡排序的时间复杂度为 O(n²),效率较低,因此不适合处理大规模数据。其适用场景主要包括:

  • 排序算法入门学习(理解交换排序的核心思想);

  • 处理小规模数据(数据量n ≤ 1000,对效率要求不高);

  • 数组接近有序的场景(优化版本可快速退出,效率接近 O(n))。

六、总结

冒泡排序是最基础的排序算法之一,核心是“相邻比较、逐步冒泡”。虽然效率不高,但原理简单、代码实现容易,是入门排序算法的绝佳选择。本文介绍了冒泡排序的原理、过程演示、基础版与优化版C++代码,并分析了其性能和适用场景。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 16:04:58

Python爬取科目一题库1685道并生成Word文档

Python爬取科目一题库1685道并生成Word文档 在准备机动车驾驶人理论考试&#xff08;科目一&#xff09;的过程中&#xff0c;很多人会遇到这样一个痛点&#xff1a;题库分散在网页上&#xff0c;每次只能手动点击“下一题”查看&#xff0c;复习效率低&#xff0c;打印也不方…

作者头像 李华
网站建设 2026/4/1 6:28:55

vLLM-Ascend 部署推理服务化的实践记录

一、前言 随着大模型技术的快速发展&#xff0c;高效推理已成为实际落地的关键挑战。vLLM 作为当前主流的大语言模型&#xff08;LLM&#xff09;推理框架&#xff0c;凭借它 PagedAttention 内存管理机制和 Continuous Batching 调度策略&#xff0c;在吞吐量和显存利用率方面…

作者头像 李华
网站建设 2026/3/26 7:03:37

什么是 ‘Lock-step’ 架构?解析高可靠 CPU 如何通过两颗芯片同时运行对比结果来检测硬件错误

各位同学&#xff0c;大家好&#xff01;今天我们来探讨一个在高可靠性计算领域至关重要的架构——’Lock-step’ 架构。作为一名编程专家&#xff0c;我深知硬件在支撑软件运行中的基础作用&#xff0c;以及硬件可靠性对于整个系统稳定性的决定性影响。在许多关键应用场景中&a…

作者头像 李华
网站建设 2026/3/21 16:27:17

微信小程序使用wxml-to-canvas生成海报并保存相册

微信小程序使用 wxml-to-canvas 生成海报并保存相册 在当前的小程序生态中&#xff0c;用户分享已成为许多产品实现增长裂变的关键路径。尤其是在教育打卡、社交邀请、活动推广等场景下&#xff0c;一张设计精良的个性化海报不仅能提升品牌质感&#xff0c;还能显著增强用户的成…

作者头像 李华
网站建设 2026/4/1 8:00:54

Spark集群搭建与任务提交实战笔记

Spark集群搭建与任务提交实战笔记 在真实生产环境中部署Spark&#xff0c;从来都不是简单地解压一个包、改几个配置文件就能搞定的事。即便是照着文档一步步操作&#xff0c;也常常会因为路径配置错误、依赖缺失或端口冲突导致集群起不来。最近一次为团队搭建测试环境时&#x…

作者头像 李华