排序算法(3)之冒泡排序

 个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

排序算法(3)之冒泡排序

收录于专栏【数据结构初阶
本专栏旨在分享学习数据结构学习的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1.常见排序算法

2.冒泡排序

2.1冒泡排序的概念

2.2冒泡排序的示例

2.3冒泡排序的动图演示

2.4冒泡排序的代码展示

2.5冒泡排序的优化

2.6测试代码

2.6.1未经优化的冒泡排序

2.6.2经过优化的冒泡排序

2.7时间复杂度分析

3.总结


今天说的是常见排序算法中的冒泡排序,本来是想和快排放在一起的,但快排的内容实在太多了,所以只能它和快排分开来说,欢迎大家点赞👍 收藏✨ 留言✉ 加关注💓

1.常见排序算法

2.冒泡排序

2.1冒泡排序的概念

冒泡排序是一种基本的比较排序算法,其名称由其排序过程中较小或较大的元素像气泡一样从数组的一端“浮”到另一端而来。其基本思想是通过反复交换相邻的未按次序排列的元素,从而使较小(或较大)的元素逐步“浮”到数组的顶端,而较大(或较小)的元素则“沉”到数组的底端。

2.2冒泡排序的示例

假设有数组 [5, 3, 8, 4, 2],使用冒泡排序的过程如下:

  • 第一次排序:比较并交换 [5, 3] -> [3, 5], [5, 8] -> [5, 8], [8, 4] -> [4, 8], [8, 2] -> [2, 8]。此时最大的元素 8 已经位于数组的最后。
  • 第二次排序:比较并交换 [3, 5] -> [3, 5], [5, 4] -> [4, 5], [5, 2] -> [2, 5]。此时第二大的元素 5 已经位于倒数第二位。
  • 第三次排序:比较并交换 [3, 4] -> [3, 4], [4, 2] -> [2, 4]。此时第三大的元素 4 位于倒数第三位。
  • 第四次排序:比较并交换 [3, 2] -> [2, 3]。此时第四大的元素 3 位于倒数第四位。

最终排序结果为 [2, 3, 4, 5, 8]。

2.3冒泡排序的动图演示

冒泡排序的步骤:

  1. 比较相邻元素:从数组的第一个元素开始,依次比较相邻的两个元素。

  2. 交换元素位置:如果发现第一个元素比第二个元素大(或小),则交换它们的位置,以使较小(或较大)的元素向前移动一位。

  3. 移动到下一对相邻元素:继续向数组的下一对相邻元素应用步骤 1 和步骤 2,直到数组末尾。此时,最后的元素会是数组中的最大(或最小)值。

  4. 重复以上步骤:重复以上步骤,每次减少未排序元素的数量,直到整个数组排序完成。

 

2.4冒泡排序的代码展示

注意:Swap函数是我已经实现了的函数,如果大家没有实现可以通过另一个变量来完成

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				swap(&a[i - 1], &a[i]);
			}
		}
	}
}

Swap函数 

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

2.5冒泡排序的优化

当某一趟排序未发生任何交换时,即可判断数组已经排好序,可以提前结束排序过程。这种优化在最佳情况下(数组已经有序)能够将时间复杂度降至 O(n)。

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		// 单趟
		int flag = 0;
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				flag = 1;
			}
		}

		if (flag == 0)
		{
			break;
		}
	}
}

优化 (if (flag == 0) break;):在每一趟排序结束后,通过检查 flag 的值,如果 flag 仍为 0,表示数组已经是有序的,可以提前结束排序过程,避免不必要的比较。

2.6测试代码

--测试oj链接--912. 排序数组 - 力扣(LeetCode)

2.6.1未经优化的冒泡排序

代码:

void Swap(int* p1, int* p2)
{
	int a = *p1;
	*p1 = *p2;
	*p2 = a;
}

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
			}
		}
	}
}

int* sortArray(int* nums, int numsSize, int* returnSize) {
    (*returnSize) = numsSize;
    int* array = (int*)malloc(sizeof(int)*(*returnSize));
    for(int i = 0; i < numsSize; i++)
    {
        array[i] = nums[i];
    }
    BubbleSort(array, numsSize);
    return array;
}

结果只通过了10个例子

 

2.6.2经过优化的冒泡排序

代码

void Swap(int* n, int* m)
{
    int p = *n;
    *n = *m;
    *m = p;

}

void BubbleSort(int* a, int n)
{
	for(int j = 0; j < n; j++)
    {
        int flag = 0;
        for(int i = 1; i < n - j; i++)
        {
            if(a[i-1] > a[i])
            {
                Swap(&a[i-1], &a[i]);
                flag = 1;
            }
        }
        if(!flag) break;
    }
}

int* sortArray(int* nums, int numsSize, int* returnSize) {
    (*returnSize) = numsSize;
    int* array = (int*)malloc(sizeof(int)*(*returnSize));
    for(int i = 0; i < numsSize; i++)
    {
        array[i] = nums[i];
    }
    BubbleSort(array, numsSize);
    return array;
}

结果也只通过了十个例子(有序序列很少见,优化后仍然大部分是O(N^2) 

2.7时间复杂度分析

时间复杂度

冒泡排序的时间复杂度取决于比较和交换的次数。

  • 最好情况时间复杂度: 当输入数组已经是按升序排列时,每一趟排序都不需要交换,只需进行 n-1 次比较。因此,最好情况时间复杂度为 O(n)

  • 最坏情况时间复杂度: 当输入数组按降序排列时,每一对相邻元素都需要交换,每趟排序需要进行 n-1 次交换操作和比较。因此,最坏情况时间复杂度为 O(n^2)

  • 平均情况时间复杂度: 平均情况下,冒泡排序的时间复杂度也是 O(n^2)。这是因为无论初始输入如何,都需要进行大致相同数量的比较和交换操作。

冒泡排序在最好情况下的优化是通过设置一个标志位(例如 flag)来检测是否进行了交换,如果某一趟排序中没有发生交换,则认为数组已经有序,可以提前结束排序过程,从而将最好情况的时间复杂度优化到 O(n)。

空间复杂度

冒泡排序的空间复杂度是 O(1),即它是一个原地排序算法。除了输入数组外,它只需要常数级别的额外空间来存储几个临时变量,如循环中的索引和交换时的临时变量。

3.总结

冒泡排序的时间复杂度主要由比较和交换操作决定,最好情况下可以达到 O(n),最坏和平均情况下为 O(n^2)。其空间复杂度为 O(1),在空间使用上非常高效。尽管冒泡排序在大规模数据上不如快速排序、归并排序等更高效的排序算法,但它的实现简单直观,适用于小型数据集或者作为教学和理解排序算法的基础。

快速排序已经在加更中,欢迎 点赞👍 收藏✨ 留言✉ 加关注💓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/803006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超详细Python安装教程(包含python解释器和pycharm)

目录 一&#xff0c;安装python解释器 二&#xff0c;安装PyCharm开发工具 一&#xff0c;安装python解释器 下载地址&#xff1a;https://www.python.org/downloads/ 如果是在windows上下载的话&#xff0c;选择Downloads->Windows 我选择了最新版本的64位安装&#xf…

RSTP和STP

RSTP&#xff08;Rapid Spanning Tree Protocol&#xff0c;快速生成树协议&#xff09;是STP&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09;的一个改进版本&#xff0c;主要区别在于RSTP通过引入新的机制来加快网络的收敛速度。具体来说&#xff1a; …

数据分析案例-2024 年热门动漫数据集可视化分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

黑马点评-Postman卡住sending Requst原因解决

不知道为什么&#xff0c;用这个c1e1d5的token就会一直卡死&#xff0c;但是换了一个token就解决了&#xff0c;目前不知道为什么 解决了&#xff0c;原来是这个请求下面的函数发生了死循环&#xff01;&#xff01;太瓜皮了我超&#xff01; 把num写成了count&#xff0c;导…

7月18日Workshop新加坡专场:在Sui上创建您自己的token

您是base在新加坡&#x1f1f8;&#x1f1ec;的开发者吗&#xff1f; 您是否觉得编程课程枯燥乏味&#xff1f;&#x1f914; 那么&#xff0c;Sui和Metaschool将一起来为您的学习增添乐趣&#xff01; 欢迎加入我们特别为Web3初学者、开发者设组织的“在Sui上创建您自己的t…

linux下Jenkins的安装部署

前言&#xff1a; 用docker安装Jenkins非常方便快捷&#xff0c;但是最近国内的docker镜像源都不好用了&#xff0c;这里回顾一下最原始的Jenkins安装方式 安装前准备 安装环境 Jenkins的运行依赖java环境&#xff0c;linux下jdk的安装参考&#xff1a;linux下JDK的安装-CSD…

2024“狮舞齐鲁”南北狮王争霸赛在临沭开锣

锣鼓声声&#xff0c;狮王争霸。5月2日&#xff0c;临沭县红色朱村旅游区内人头攒动&#xff0c;热闹非凡。备受瞩目的“狮舞齐鲁”南北狮王争霸赛在此开赛&#xff0c;吸引了来自山东省的40支队伍、400余名参赛选手齐聚一堂&#xff0c;共同献上一场精彩绝伦的舞狮盛宴。 此次…

检测机构的配方分析是怎样?

检测机构配方分析是指检测机构通过对样品的化学成分、结构和性质进行分析&#xff0c;以确定其组成和配方的一种服务。检测机构通常提供以下服务&#xff1a; 1. 样品采集与前处理&#xff1a;检测机构通常会指导客户采集具有代表性的样品&#xff0c;并进行必要的前处理&#…

Blender练习,凳面以及凳脚的制作

目录 ​ 1.凳面的制作 2.制作坐垫下面的两条杠 3.制作桌腿 要制作的凳子如图&#xff0c;可以看到&#xff0c;它是一个由长方体&#xff0c;圆柱体等多种几何图形合成的一个立体图形 1.凳面的制作 shifta创建一个正方体 ctrltab打开一个弹窗&#xff0c;选择编辑模式。…

Linux离线安装Mysql5.7

Linux之Mysql安装配置 第一种&#xff1a;Linux离线安装Mysql&#xff08;提前手动下载好tar.gz包&#xff09; 第二种&#xff1a;通过yum安装配置Mysql&#xff08;服务器有网络&#xff09; 之前在阿里云上采用yum安装过一次&#xff08;请看这里&#xff09;&#xff0c;…

区块链资料

Quantstamp - Public Security Assessments smart-contract-sanctuary-bsc/contracts/mainnet at master tintinweb/smart-contract-sanctuary-bsc GitHub https://github.com/slowmist/Cryptocurrency-Security-Audit-Guide/blob/main/README_CN.md sFuzz: 高效自适应的智…

SpringBoot结合ip2region实现博客评论显示IP属地

你好呀&#xff0c;我是小邹。 在现代的Web应用中&#xff0c;特别是博客和论坛类网站&#xff0c;为用户提供地理定位服务&#xff08;如显示用户所在地理位置&#xff09;可以极大地增强用户体验。本文将详细探讨如何使用Java和相关技术栈来实现在博客评论中显示用户的地址信…

大雾弥散动态特效404单页源码

源码介绍 大雾弥散动态特效404单页源码,跟随鼠标反向移动,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head><meta charset="utf-8&quo…

react自定义校验报错问题修复 ProFormText

1、以下是tsx组件 自定义校验告警导致表单无法提交问题修复 修改如下&#xff1a;

Spring使用外部的属性文件

首先&#xff0c; 我们在Spring里配置一个数据源Datasource&#xff0c;看具体代码&#xff1a; 我们说这样配置数据源&#xff0c;是可以实现&#xff0c; 但是我们不建议讲数据源配置在Spring的配置文件里&#xff0c;因为&#xff0c;这里会配置很多bean&#xff0c;而我们的…

W外链创建抖音私信卡片教程,私信卡片跳转微信工具

W外链地址wai.cn 在数字化时代的浪潮中&#xff0c;私域流量的价值愈发凸显&#xff0c;成为企业获取用户、建立品牌忠诚度、提升转化率的关键手段。抖音&#xff0c;作为当下最热门的短视频社交平台之一&#xff0c;其用户基数庞大、互动性强&#xff0c;为企业私域引流提供了…

爬虫(一)——爬取快手无水印视频

前言 最近对爬虫比较感兴趣&#xff0c;于是浅浅学习了一些关于爬虫的知识。爬虫可以实现很多功能&#xff0c;非常有意思&#xff0c;在这里也分享给大家。由于爬虫能实现的功能太多&#xff0c;而且具体的实现方式也有所不同&#xff0c;所以这里开辟了一个新的系列——爬虫…

FY4B卫星L2级产品掌握和python处理

废话不多说&#xff0c;展示二级产品CTT为例&#xff1a; 抱歉没空了解FY4B产品情况了&#xff0c;直接看代码 # CTT色标配置 bounds_CTT [180, 200, 220, 240, 260, 280, 300, 320] # 根据你的数据设定 colors_CTT [(0, 0, 139/255),(10/255, 0, 245/255),(0, 164/255, 2…

C语言——详解二维数组中元素的地址

在C语言中&#xff0c;二维数组元素的地址认知是一个相对复杂但重要的概念。以下是对二维数组中元素地址认知的详细叙述&#xff1a; 一、二维数组的基本构成 二维数组可以被看作是由多个一维数组组成的数组。例如&#xff0c;定义了一个3行4列的二维数组&#xff0c; int a…

实战分享:利用百数实现通讯录与表单无缝对接,提升管理效率

百数的通讯录实时同步到表单功能&#xff0c;实现了员工信息的即时更新与自动整合&#xff0c;不仅极大地提升了信息管理的效率与准确性&#xff0c;还为企业提供了便捷的数据分析基础&#xff0c;助力企业更高效地运营与决策。 设置方式 在企业管理中&#xff0c;开启通讯录…