当前位置: 首页 > news >正文

【经典算法学习-排序篇】冒泡排序

一、冒泡排序

1.基本概念和介绍

冒泡排序的基本思想:依次比较相邻的两个是否逆序对,若逆序就交换。

  • 冒牌排序

冒泡排序的思想理解起来非常简单:以n个数为例,从第1个数开始,依次比较,即第1个和第2个比,若第1个数比第2个数大,就交换两数。以此类推,直到第n-1个数和第n个做比较。

像这样,把最大的数排在最后,即将最大的数像冒泡一样逐步冒到相应的位置。就这样,一个n个数排序的问题就转换为了n-1个数的排序问题。如此进行n-1此后,队列变为了有序队列。 

我们可以使用一幅动图来解释:

 2.冒泡排序

e.g.1: 输入n个数,将这n个数按照从小到大排序。

  • 输入

输入一个数字n和一个长度为n的序列,通常将这n个数直接放进数组中。

  • 输出

输出一个新序列,满足按照从小到大的顺序排序

啊对对对
  • 算法说明

冒泡排序的基本大致流程如下:

  1. 读入数据,将数据存放到a数组中;
  2. 比较相邻的两个数据,如果前面的数据大于后面的数据,就将两数交换;
  3. 对数组的第1个到底n个数进行一次遍历以后,最大的数就冒到了数组第n个位置;
  4. n = n - 1,如果n不为1,就重复步骤②步骤③,否则排序完成。

 

3.代码实现

#include <iostream>

using namespace std;

int main()
{
	int a[1024],n;
	cin >> n;
	for(int i = 0; i < n; i ++)
	{
		cin >> a[i];
	}
	for(int i = 0; i < n; i ++)
	{
		for(int j = 0; j < n - i - 1; j ++)
		{
			if(a[j] > a[j+1])
			{
				swap(a[j], a[j+1]);
			}
		}
	}
	for(int i = 0; i < n; i ++) {
		cout << a[i] << " ";
	}
	return 0;
}

4.时间复杂度分析

  • 最优情况

最优情况莫过于是正向有序,只需要进行一趟排序,即比较n-1次就可以了。此时,一共交换了0次,时间复杂度为O(n).

  • 最差情况

最差情况恰好和最优情况相反,在序列为逆向有序时,进行n-1趟排序,比较n-1次,交换n-1次,时间复杂度也就因为有两层循环而变成O(n^{2})了.

  • 平均情况

综合上述两种情况,可以得到冒泡排序的时间复杂度为:

\frac{O(n) + O(n^2)}{2} = \frac{O(n + n^2)}{2} = O(n^2)

5.代码优化

对于有些数据,我们不难发现,不一定要n-1才能排完。

例如一组数据"1 5 2 3 4 6",我们发现只需要一趟排序就可以将整组序列排完了。

于是,我们可以设置一个bool类型的变量,记录本次循环是否有进行交换,如果没有就可以直接跳出循环了。

#include <iostream>

using namespace std;

int main()
{
	int a[1024],n;
	bool flag;
	cin >> n;
	for(int i = 0; i < n; i ++)
	{
		cin >> a[i];
	}
	for(int i = 0; i < n; i ++)
	{
		flag = true;
		for(int j = 0; j < n - i - 1; j ++)
		{
			if(a[j] > a[j+1])
			{
				swap(a[j], a[j+1]);
			}
			flag = false;
		}
		if(flag == true)
		{
			break; // 没有进行交换,直接跳出循环 
		}
	}
	for(int i = 0; i < n; i ++) 
	{
		cout << a[i] << " ";
	}
	return 0;
}

二、总结

冒泡排序是最基本的一种算法,大部分人所学习的第一个排序算法便是冒泡排序。

冒泡排序的优势在于冒泡排序具有稳定性。但是,其时间复杂度却略有逊色,所以冒泡排序的速度相比较而言就慢了许多。

三、课后小练习

没有课后小练习怎么行?!

奉上今日的课后题单,各位大佬们一定要接受这份提题单!

求知若渴,虚心若愚。

https://www.luogu.com.cn/problem/P2676

车厢重组 - 洛谷

四、下期预告

这回真是木桶效应.... 

相关文章:

  • Nacos系列【26】源码分析篇之客户端自动注册
  • DBeaver常用快捷键(含复制当前行)
  • Java ThreadPoolExecutor的拒绝策略
  • 操作系统——磁盘操作
  • DSPE-PEG-FSHB,FSHB-PEG-DSPE,磷脂-聚乙二醇-靶向多肽FSHB
  • JAVA 力扣练习题:回文数
  • 【Git】credential.helper
  • PDF格式分析(六十九)——注释字典
  • mysql45讲记录
  • 软件测试工程师要摆正自己的心态和位置
  • Vue的双向绑定及应用
  • 编程的基础知识
  • Vue介绍和入门,包括配置等
  • 编程猫创作工具:新版Kitten新体验
  • SpringBean面试题
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • const let
  • EventListener原理
  • gcc介绍及安装
  • Go 语言编译器的 //go: 详解
  • Javascript弹出层-初探
  • JAVA多线程机制解析-volatilesynchronized
  • JS字符串转数字方法总结
  • Logstash 参考指南(目录)
  • Python打包系统简单入门
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • 搞机器学习要哪些技能
  • 基于 Babel 的 npm 包最小化设置
  • 坑!为什么View.startAnimation不起作用?
  • 深度解析利用ES6进行Promise封装总结
  • 实战|智能家居行业移动应用性能分析
  • 无服务器化是企业 IT 架构的未来吗?
  • 线性表及其算法(java实现)
  • gunicorn工作原理
  • ​TypeScript都不会用,也敢说会前端?
  • #、%和$符号在OGNL表达式中经常出现
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • $().each和$.each的区别
  • $.ajax()
  • (2020)Java后端开发----(面试题和笔试题)
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • ... 是什么 ?... 有什么用处?
  • .NET DataGridView数据绑定说明
  • .Net8 Blazor 尝鲜
  • /etc/sudoer文件配置简析
  • @EnableConfigurationProperties注解使用
  • [AIGC] Redis基础命令集详细介绍
  • [BZOJ1178][Apio2009]CONVENTION会议中心
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [DevOps云实践] 彻底删除AWS云资源