news 2026/3/7 14:50:38

深入浅出冒泡排序:原理、实现与优化(附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/3 17:05:44

C++ STL基础入门详解

C STL基础入门详解 一、什么是C STL&#xff1f; STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;是C标准库的核心组成部分&#xff0c;由惠普实验室开发&#xff0c;后来被纳入C标准。它提供了一系列通用的模板类和函数&#xff0c;涵盖了数据结…

作者头像 李华
网站建设 2026/3/3 17:54:04

多通道灵活配置,16位高精度模拟量采集模块

高精度模拟量采集模块作为工业自动化领域的核心组件&#xff0c;广泛应用于需要对温度、压力、流量、电压等连续变化物理量进行精确测量的场景。其0.05%FS的高精度和10VDC、4-20mA等多量程输入特性&#xff0c;使其成为数据采集系统中的关键环节。 上位机通过RS485/RJ45给高精度…

作者头像 李华
网站建设 2026/3/1 20:40:54

B+TREE简介

btree图示btree的核心特点 b树是b树的一种变体&#xff0c;它在数据库索引中更为常见。与b树相比&#xff0c;b树有以下关键区别&#xff1a; 1、内部节点只存键&#xff0c;不存数据&#xff1a;所有数据都存储在叶子节点中。内部节点仅用于索引&#xff0c;即指引搜索方向。 …

作者头像 李华
网站建设 2026/3/3 12:46:25

GIST索引原理

gist全称是generalized search tree&#xff0c;即”通用搜索树“。它是一种平衡树结构&#xff0c;类似于B树&#xff0c;但是可以被扩展以支持任意数据类型和查询操作。 gist索引最初在1995年提出&#xff0c;目的是为了提供一个可以自定义的索引框架&#xff0c;使得开发人员…

作者头像 李华
网站建设 2026/3/5 16:57:23

为什么你的手机还不能运行Open-AutoGLM?90%人忽略的2个关键步骤

第一章&#xff1a;Open-AutoGLM怎么部署到自己手机上将 Open-AutoGLM 部署到手机上&#xff0c;可以通过轻量化推理框架结合本地模型服务实现。整个过程无需依赖云端 API&#xff0c;保障隐私的同时提升响应速度。准备工作 确保手机已开启开发者选项与 USB 调试模式安装 Termu…

作者头像 李华