【排序算法】1.冒泡排序-C语言实现

冒泡排序(Bubble Sort)是最简单和最通用的排序方法,其基本思想是:在待排序的一组数中,将相邻的两个数进行比较,若前面的数比后面的数大就交换两数,否则不交换;如此下去,直至最终完成排序 。由此可得,在排序过程中,大的数据往下沉,小的数据往上浮,就像气泡一样,于是将这种排序算法形象地称为冒泡排序 

冒泡排序_百度百科 (baidu.com)

冒泡排序适用于小规模数据和部分排序数据的情况,同时也常用于教学和理解排序算法的基本原理

1. 算法步骤

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

之后,针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

2. 动图演示

3.代码实现

#include <stdio.h>
void bubble_sort(int arr[], int len) {
        int i, j, temp;
        for (i = 0; i < len - 1; i++)
                for (j = 0; j < len - 1 - i; j++)
                        if (arr[j] > arr[j + 1]) {
                                temp = arr[j];
                                arr[j] = arr[j + 1];
                                arr[j + 1] = temp;
                        }
}
int main() {
        int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
        int len = sizeof(arr) / sizeof(arr[0]);
        bubble_sort(arr, len);
        int i;
        for (i = 0; i < len; i++)
                printf("%d ", arr[i]);
        return 0;
}

4.函数封装

升序排列

void Bubble_Sort(uint16_t *Data,uint8_t Count)
{
    uint8_t i=0,j=0;
    uint16_t temp;
    for(i=0;i<Count-1;i++)
    {
        for(j=0;j<Count-1-i;j++)
        {
            if(Data[j]>Data[j+1])
            {
               temp=Data[j];
               Data[j]=Data[j+1];
               Data[j+1]=temp;
            }
        }
    }
}

降序排列

​
void Bubble_Sort(uint16_t *Data,uint8_t Count)
{
    uint8_t i=0,j=0;
    uint16_t temp;
    for(i=0;i<Count-1;i++)
    {
        for(j=0;j<Count-1-i;j++)
        {
            if(Data[j]<Data[j+1])//改变符号
            {
               temp=Data[j];
               Data[j]=Data[j+1];
               Data[j+1]=temp;
            }
        }
    }
}

​

5.函数讲解

核心代码如下:

 for(i=0;i<Count-1;i++)
    {
        for(j=0;j<Count-1-i;j++)
        {
            if(Data[j]>Data[j+1])
            {
               temp=Data[j];
               Data[j]=Data[j+1];
               Data[j+1]=temp;
            }
        }
    }

外循环讲解

外循环其实就是已经排好的数据的个数累加过程.

i=0:一个也没有被确定,所以从0开始累加。

i<count-1:冒泡排序有Count个数,要从小到大排,内循环结束一次,就有一个数被确定,只要其中(Count-1)个较高位数的位置排好了,那么最小的数就排好了,比如三个大小不同的数,只要确定2个数,哪个最大,哪个第二大,那么第三个数就是最小。所以知道(Count-1)个较高位数的位置被确定,循环就结束。

i++:已知冒泡排序高位向后排,每一轮比较(内循环)都确定了一个最高位,这个最高位如果放在没有被排序的数里是最高位,这个最高位在已经确定位置的数里是最低位。

内循环讲解

j=0:从数组的第0个数开始遍历数组

j<count-i-1:Count个数据,需要比较(Count-1)次,而i是整个排序中被确定的数,一开始为0,每一次内结束循环结束就确定一个,就少比较i个数,所以在确定i个数的位置时,内循环需要比较的数据有(Count-i)个,数据要比较的次数为(Count-1-i)次

j++:相邻的相比较,所以加一

if条件语句为了升序比较,第一个与第二个,第二个与第三个…

if的花括号内就是C语言常用的交换位置的三个语句。

7.冒泡排序flag优化算法

冒泡排序还有一种优化算法,就是立一个 flag,当在一次数组遍历中元素没有发生交换,则证明该数组已经有序。但这种改进对于提升性能来说并没有什么太大作用。

解决方式:可以通过一个标志位来打断循环

void Bubble_Sort(uint16_t *Data,uint8_t Count)
{
    uint8_t i=0,j=0,Flag=0;
    uint16_t temp;
    for(i=0;i<Count-1;i++)
    {
        for(j=0;j<Count-1-i;j++)
        {
            if(Data[j]>Data[j+1])
            {
               temp=Data[j];
               Data[j]=Data[j+1];
               Data[j+1]=temp;
               Flag=1;
            }
        }
        if(Flag==0)
        {
            break;
        }
        else
            Flag=0;
        
    }
}

8.时间复杂度分析


冒泡排序的时间复杂度分析是衡量算法效率的重要指标。我们来分析最好情况、最坏情况和平均情况下的时间复杂度:

最好情况:如果待排序的数组已经有序,即元素无需交换位置,那么只需要进行一次遍历,时间复杂度为 O(n)。
最坏情况:如果待排序的数组是逆序的,即每次比较都需要交换位置,那么需要进行 n-1 轮遍历,每轮遍历需要比较 n-i-1 次,时间复杂度为 O(n^2)。
平均情况:在平均情况下,需要进行 n/2 轮遍历,每轮遍历需要比较 n-i-1 次,时间复杂度也为
O(n^2)。
冒泡排序的时间复杂度为 O(n^2),其中 n 表示待排序数组的长度。这说明随着数据规模的增大,冒泡排序的执行时间呈二次增长,效率较低。                       

9.性能分析

优点:


简单易懂:冒泡排序是一种非常简单的排序算法,它的思想容易理解,代码实现也相对容易。
稳定排序:冒泡排序是一种稳定的排序算法,即在排序过程中,相同大小的元素不会相互交换位置。
空间复杂度低:冒泡排序的空间复杂度为 O(1),即它只需要使用固定的额外空间来存储交换的元素,而不依赖于输入数组的大小。


缺点:


时间复杂度高:冒泡排序的时间复杂度为 O(n^2),在处理大规模数据时效率较低。
不适合大规模数据:由于冒泡排序需要进行多次比较和交换操作,对于大规模数据集,其性能可能会较差。
排序不彻底:在最坏情况下,冒泡排序可能无法将数组完全排序,例如当数组已经基本有序时。

10.总结


冒泡排序是最基础的排序算法之一,通过相邻元素的比较和交换,逐渐将最大(或最小)的元素冒泡到数列的一端。尽管冒泡排序的效率相对较低,但它的实现简单易懂,是理解排序算法的入门之选。

然而,在实际应用中,对于大规模数据集,我们更倾向于选择时间复杂度较低的排序算法,如快速排序、归并排序和堆排序等。这些算法能够在更短的时间内完成排序任务,提高程序的执行效率。因此,在实际开发中,我们需要根据具体情况选择合适的排序算法。   

                

参考博客:

JS-Sorting-Algorithm/1.bubbleSort.md at master · hustcc/JS-Sorting-Algorithm · GitHub

【干货】深入剖析冒泡排序算法:原理、步骤与复杂度分析_冒泡算法-CSDN博客

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

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

相关文章

SimMIM:一个类BERT的计算机视觉的预训练框架

1、前言 呃…好久没有写博客了&#xff0c;主要是最近时间比较少。今天来做一期视频博客的内容。本文主要讲SimMIM&#xff0c;它是一个将计算机视觉&#xff08;图像&#xff09;进行自监督训练的框架。 原论文&#xff1a;SimMIM&#xff1a;用于掩码图像建模的简单框架 (a…

支持大量边缘盒子集中管理调度的智慧物流开源了。

智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。用户只需在界面上…

在golang中Sprintf和Printf 的区别

最近一直在学习golang这个编程语言&#xff0c;我们这里做一个笔记就是 Sprintf和Printf 的区别 fmt.Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。 fmt.Printf 根据格式化参数生成格式化的字符串并写入标准输出。由上面就可以知道&#xff0c;fmt.Sprintf返回的…

NodeJS技巧:在循环中管理异步函数的执行次数

背景介绍 在现代Web开发中&#xff0c;NodeJS因其高效的异步处理能力而备受青睐。尤其在数据抓取、网络爬虫等应用场景中&#xff0c;NodeJS的非阻塞I/O特性使其成为不二之选。然而&#xff0c;在实际编程过程中&#xff0c;我们经常会遇到一个棘手的问题——如何在循环中控制…

初识Docker及管理Docker

Docker部署 初识DockerDocker是什么Docker的核心概念镜像容器仓库 容器优点容器在内核中支持2种重要技术&#xff1a;Docker容器与虚拟机的区别 安装Docker源码安装yum安装检查Docker Docker 镜像操作配置镜像加速器&#xff08;阿里系&#xff09;搜索镜像获取镜像查看镜像信息…

python实现九九乘法表

1.self i 1 while i<9:j 1while j< i:print("j * i ",end)print(j * i ,end)print(" ",end)j 1i 1print() 实现结果&#xff1a; 2.改进 i 1 while i<9:j 1while j< i:# print("j * i ",end)# print(j * i ,end)# print(&…

CSA笔记1-基础知识和目录管理命令

[litonglocalhost ~]$ 是终端提示符&#xff0c;类似于Windows下的cmd的命令行 litong 当前系统登录的用户名 分隔符 localhost 当前机器名称&#xff0c;本地主机 ~ 当前用户的家目录 $ 表示当前用户为普通用户若为#则表示当前用户为超级管理员 su root 切换root权限…

详解曼达拉升级:如何用网络拓扑结构扩容BSV区块链

​​发表时间&#xff1a;2024年5月24日 BSV曼达拉升级是对BSV基础设施的战略性重塑&#xff0c;意在显著增强其性能&#xff0c;运行效率和可扩容。该概念于2018年提出&#xff0c;其战略落地将使BSV区块链顺利过渡&#xff0c;从现有的基于单一集成功能组件的网络拓扑结构&am…

java面向对象进阶篇--static

一、前言 java进阶篇已经开始了&#xff0c;先从面向对象开始&#xff0c;由于时间原因今天就只更新了static部分&#xff0c;内容上特别详细&#xff0c;一些特别的注意事项也在反复的提醒大家。 温馨提示一下&#xff0c;往后的java篇会越来越难&#xff0c;希望大家能够坚…

Logistic回归(Logistic Regression)

机器学习的分类问题&#xff0c;使用logistics回归&#xff08;虽然叫回归&#xff0c;但是是做分类任务的&#xff09; 一&#xff1a;简介 MINIST Dataset 一个手写数字的数据集 其中有10分类&#xff0c;0&#xff0c;1&#xff0c;2&#xff0c;....&#xff0c;9 未来y…

002uboot Makefile分析

1.分析配置过程 我们把补丁文件打到uboot源码中&#xff0c;&#xff08;补丁文件时根据自己的板子所修改的代码&#xff09;&#xff0c;然后看一下Makefile。 make 100ask24x0_config #这个指令用来配置uboot打入补丁文件后 Makefile中会自动的生成这样的代码&#xff0c;我…

mybatis动态传入参数 pgsql 日期 Interval ,day,minute

mybatis动态传入参数 pgsql 日期 Interval 在navicat中&#xff0c;标准写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL 5 day)在mybatis中&#xff0c;错误写法 SELECT * FROM test WHERE time > (NOW() - INTERVAL#{numbers,jdbcTypeINTEGER} day)报错内…

王道计算机考研数据结构思维导图笔记(持续更新)

第1章 绪论 1.1 数据结构的基本概念 1.1.1 基本概念和术语 1.1.1 数据结构三要素 1.2 算法和算法评价 1.2.1算法的基本概念 1.2.2 算法效率的度量 第2章 线性表 2.1 线性表的定义和基本操作 2.1.1 线性表的定义 2.1.2 线性表的基本操作 2.2.1 顺序表上的定义 2.2.2 顺序…

UE4-光照渲染、自动曝光、雾

目录 一.光源种类 二.灯光的移动性 三.自动曝光 四.指数级高度雾 五.实现光束 一.光源种类 1.定向光源 用来模拟现实中的太阳光。 2.点光源 比如现实中的灯泡 3.聚光源 4.矩形光源 是这几个光源中性能开销最大的&#xff0c;一般不用到游戏场景中&#xff0c;因为游…

项目方案:视频图像结构化分析技术在车辆和人体检测中的应用方案(视频公共安全领域的解决方案)

目录 一、视频结构化分析技术介绍 1、概述 2、定义 3、核心环节 4、应用领域 二、视频中车辆和人的结构化 1、需求 2、信息内容 3、功能说明 &#xff08;1&#xff09;信息智能识别功能 &#xff08;2&#xff09;智能检索功能 &#xff08;3&#xff09;数据统计…

vue学习day11-路由、路由模块的封装、声明式导航-路由的介绍、VueRouter、router-link、自定义高亮类名

32、路由 &#xff08;1&#xff09;路由的介绍 1&#xff09;生活中的路由&#xff1a;设备和ip的映射关系 2&#xff09;路由&#xff1a;一种映射关系 3&#xff09;Vue中的路由&#xff1a;路径与组件的映射关系 &#xff08;根据路由就能知道不同的路径&#xff0c;应…

骑行耳机哪款性价比高?五大热销骑行耳机推荐!

骨传导耳机凭借不入耳佩戴更健康的优点&#xff0c;短时间内迅速风靡骑行圈&#xff0c;其独特的设计不仅为骑行爱好者带来了前所未有的听觉体验&#xff0c;还完美兼顾了安全与便捷。骑行途中&#xff0c;它能够让你在享受音乐的同时&#xff0c;依然保持对周围环境的敏锐感知…

Milvus 核心设计(5)--- scalar indexwork mechanism

目录 背景 Scalar index 简介 属性过滤 扫描数据段 相似性搜索 返回结果 举例说明 1. 属性过滤 2. 扫描数据段 3. 相似性搜索 实际应用中的考虑 Scalar Index 方式 Auto indexing Inverted indexing 背景 继续Milvus的很细设计&#xff0c;前面主要阐述了Milvu…

Java面试八股之Redis哨兵机制

Redis哨兵机制 Redis Sentinel&#xff08;哨兵&#xff09;模式是一种高可用解决方案&#xff0c;用于监控和自动故障转移Redis主从集群。以下是对哨兵模式详细过程的描述&#xff1a; 1. 初始化与配置 部署哨兵节点&#xff1a;在不同的服务器上部署一个或多个Redis Sentin…

达梦数据库的系统视图v$dict_cache_item

达梦数据库的系统视图v$dict_cache_item 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$DICT_CACHE_ITEM 是一个系统视图&#xff0c;用于显示字典缓存&#xff08;Dictionary Cache&#xff09;中的项信息。字典缓存是数据库中的一个重要组件&#xff0c;…