C语言冒泡排序教程简介
冒泡排序(Bubble Sort)是一种简单的排序算法,因其工作原理像气泡一样逐渐上浮而得名。其基本思想是通过一轮一轮地比较相邻的元素,将较大的元素逐步“冒泡”到数组的尾部。
在本篇博客中,我们将详细讲解冒泡排序的基本概念,如何在C语言中实现冒泡排序,并提供一些示例来帮助大家理解。
一、冒泡排序的原理
冒泡排序的核心思想是:通过多次遍历数组,将较大的元素逐步交换到数组的末端。每一轮遍历都会将一个最大的元素“冒泡”到正确的位置。
假设我们有一个数组 [5, 3, 8, 4, 2],冒泡排序的过程如下:
-
第一轮遍历:
- 比较
5和3,因为5 > 3,交换它们。 - 比较
5和8,无需交换。 - 比较
8和4,因为8 > 4,交换它们。 - 比较
8和2,因为8 > 2,交换它们。
第一轮之后,数组变成:
[3, 5, 4, 2, 8]。此时,最大值8已经排好位置。 - 比较
-
第二轮遍历:
- 比较
3和5,无需交换。 - 比较
5和4,因为5 > 4,交换它们。 - 比较
5和2,因为5 > 2,交换它们。
第二轮之后,数组变成:
[3, 4, 2, 5, 8]。最大值5已经排好位置。 - 比较
-
第三轮遍历:
- 比较
3和4,无需交换。 - 比较
4和2,因为4 > 2,交换它们。
第三轮之后,数组变成:
[3, 2, 4, 5, 8]。最大值4已经排好位置。 - 比较
-
第四轮遍历:
- 比较
3和2,因为3 > 2,交换它们。
第四轮之后,数组变成:
[2, 3, 4, 5, 8]。此时,所有元素已经按升序排列。 - 比较
二、冒泡排序的代码实现
现在,让我们通过C语言代码来实现冒泡排序。
#include <stdio.h>// 冒泡排序函数
void bubbleSort(int arr[], int n) {// 外层循环控制总的轮数for (int i = 0; i < n - 1; i++) {// 内层循环进行相邻元素的比较与交换for (int j = 0; j < n - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交换元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}// 输出数组
void printArray(int arr[], int n) {for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {int arr[] = {5, 3, 8, 4, 2}; // 初始化数组int n = sizeof(arr) / sizeof(arr[0]); // 计算数组元素个数printf("排序前的数组: ");printArray(arr, n); // 输出排序前的数组bubbleSort(arr, n); // 调用冒泡排序函数printf("排序后的数组: ");printArray(arr, n); // 输出排序后的数组return 0;
}
三、代码分析
-
bubbleSort函数- 外层循环控制冒泡的轮数,每一轮都会将一个最大的元素“冒泡”到正确的位置。
- 内层循环比较相邻的元素,如果前一个元素大于后一个元素,则交换它们的位置。
- 注意:内层循环的次数随着外层循环的进行逐渐减少,因为每轮排序之后,最大的元素已经排好位置。
-
printArray函数- 用于输出数组中的元素,帮助我们查看排序前后的数组状态。
-
main函数- 创建一个数组,并初始化。
- 输出排序前的数组。
- 调用
bubbleSort函数进行排序。 - 输出排序后的数组。
四、冒泡排序的时间复杂度
冒泡排序的时间复杂度为 O(n²),其中 n 是数组的长度。由于冒泡排序需要进行两层嵌套循环:外层循环进行 n - 1 次遍历,内层循环最多进行 n - i 次比较和交换。
- 最好情况:如果数组已经是有序的,冒泡排序仍然会进行 n - 1 轮遍历。此时,时间复杂度为 O(n),但这是一个理想情况。
- 最坏情况:如果数组是逆序排列的,每一轮遍历都需要交换元素,时间复杂度为 O(n²)。
- 平均情况:大部分情况下,时间复杂度为 O(n²)。
五、冒泡排序的优缺点
优点:
- 简单易懂:冒泡排序是最简单的排序算法之一,非常适合初学者理解。
- 原地排序:不需要额外的存储空间,只需常数空间。
缺点:
- 效率低下:时间复杂度较高,特别是在处理大规模数据时,效率较低。
- 交换次数多:在排序过程中频繁交换元素,可能会消耗较多的时间。
六、总结
冒泡排序是一种简单的排序算法,适合小规模数据的排序。当数据量较大时,冒泡排序的效率较低,通常不推荐使用。在实际开发中,我们更常使用其他更高效的排序算法,如快速排序或归并排序。
希望通过这篇博客,大家能够掌握冒泡排序的基本思想和实现方式,并能在实际编程中灵活运用。如果你有任何问题或疑惑,欢迎在评论区留言,我们一起讨论。
相关文章:
C语言冒泡排序教程简介
冒泡排序(Bubble Sort)是一种简单的排序算法,因其工作原理像气泡一样逐渐上浮而得名。其基本思想是通过一轮一轮地比较相邻的元素,将较大的元素逐步“冒泡”到数组的尾部。 在本篇博客中,我们将详细讲解冒泡排序的基本…...
Fabric链码部署测试
参考链接:运行 Fabric 应用程序 — Hyperledger Fabric Docs 主文档 (hyperledger-fabric.readthedocs.io) (2)fabric2.4.3部署运行自己的链码 - 知乎 (zhihu.com) Fabric2.0测试网络部署链码 - 辉哥哥~ - 博客园 (cnblogs.com) 1.启动测试…...
k620老显卡,装cuda.等。
CUDA安装教程(超详细)-CSDN博客 1.下载支持12.0以上的驱动 NVIDIA RTX Driver Release 550 R550 U12 (553.50) | Windows 11 解压。安装。一路下一步。查看结果 2.下载 cuda CUDA Toolkit Archive | NVIDIA Developer 安装cuda时,第一次…...
网站常用功能模块-鉴权
一:JWT是什么? 常用鉴权方式有很多种,今天主要介绍基于token的鉴权方式JWT(Json JSON Web Token)。因为这种方式实现起来方便快捷。整体实现逻辑如下 第一次登陆时,前端携带账号和密码请求登录接口。服务…...
直接插入排序、折半插入排序、2路插入排序、希尔排序
本篇是排序专栏博客的第一篇,主要探讨以 “插入” 为核心思想的排序算法该如何实现 文章目录 一、前言二、直接插入排序1. 算法思想与操作分析2. 代码实现version 1version 2 3. 复杂度分析 三、折半插入排序1. 算法思想与操作分析2. 代码实现3. 复杂度分析 四、2路…...
FQ-GAN代码解析
主要看 model 、loss 和 data 部分如何实现和处理的。 model—VQ_modelsVQModelEncoderVectorQuantizerDecoder loss—VQLoss_triple_codebook model—VQ_models 创建vq_model直接根据传入的模型压缩倍率8/16初始化对应的VQ_8/VQ_16,两者都是初始化一个VQModel的类…...
如何恢复已删除的 Telegram 消息 [iOSamp;Android]
Telegram 是一款功能强大的消息应用程序,因其易用性、隐私保护和众多炫酷功能而深受用户喜爱。然而,有时我们会不小心删除重要的消息。在这种情况下你应该做什么? 本文将为您提供简单有效的解决方案来恢复 Telegram 上已删除的消息ÿ…...
asp.net core中的 Cookie 和 Session
在 Web 开发中,用户会话管理是非常重要的,尤其是在需要保持用户状态和身份验证的应用中。ASP.NET Core 提供了多种状态管理技术,如 Cookie 和 Session,它们可以帮助你管理用户会话、存储数据并实现用户身份验证等功能。下面将详细…...
Python实现一个简单的 HTTP echo 服务器
一个用来做测试的简单的 HTTP echo 服务器。 from http.server import HTTPServer, BaseHTTPRequestHandler import jsonclass EchoHandler(BaseHTTPRequestHandler):def do_GET(self):# 构造响应数据response_data {path: self.path,method: GET,headers: dict(self.headers…...
Ruby 中文编码
Ruby 中文编码 在 Ruby 编程语言中处理中文编码是一个常见的需求,尤其是在中国和其他使用中文的地区。Ruby 是一种动态、开放源代码的编程语言,它支持多种字符编码,包括中文编码。本文将探讨在 Ruby 中处理中文编码的几种方法,以…...
淘金优化算法的信息共享与更新机制改进
淘金优化算法作为一种模拟自然界淘金过程的启发式搜索算法,在解决复杂优化问题时展现出独特优势。然而,其性能在很大程度上依赖于信息共享与更新机制的有效性。传统机制在面对高维、多模态等复杂问题时,往往存在信息交流不畅、更新滞后等问题,导致算法陷入局部最优或收敛速…...
Python中的ast.literal_eval:安全地解析字符串为Python对象
Python中的ast.literal_eval:安全地解析字符串为Python对象 什么是ast.literal_eval?为什么说它是“安全”的? 如何使用ast.literal_eval?示例1:将字符串转换为列表示例2:将字符串转换为字典示例3ÿ…...
【AI数学基础】线性代数:内积和范数
(观前提醒,这是工科AI相关的数学基础的学习笔记,不是数学专业的文章,所以没有严谨的证明和定义,数院大神请勿批评) 2. 内积和范数 2.1 内积的定义 从代数的角度来说,内积是两个向量之间的一种…...
Go语言的 的泛型(Generics)核心知识
Go语言的泛型(Generics)核心知识 引言 在编程语言的发展历程中,泛型是一项重要的特性。它使得程序员能够编写更加灵活和可重用的代码,减少了代码重复,提高了类型安全性和性能。从最初的C和Java,到现代的R…...
C++vector
1. vector 的介绍及使用 1.1vector的介绍 vector的文档介绍 1.vector是表示可变大小数组的序列容器 2.就像数组一样,vector也采用的连续存储空间来存储元素,也就是意味着可以采用下标对vector 的元素进行访问,和数组一样高效但是又不像数组…...
如何配置【Docker镜像】加速器+【Docker镜像】的使用
一、配置Docker镜像加速器 1. 安装/升级容器引擎客户端 推荐安装1.11.2以上版本的容器引擎客户端 2. 配置镜像加速器 针对容器引擎客户端版本大于1.11.2的用户 以root用户登录容器引擎所在的虚拟机 修改 "/etc/docker/daemon.json" 文件(如果没有…...
Docker--Docker Network(网络)
Docker Network(网络)是Docker容器之间和容器与外部网络之间的通信和连接的一种机制。以下是对Docker Network的详细解释: 一、Docker网络的重要性 Docker容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作…...
Vue项目中生成node_modules文件夹的两种常用方法及npm优势
在Vue项目中生成node_modules文件夹的过程非常简单,主要步骤如下: 1、使用 npm 安装依赖包; 2、使用 yarn 安装依赖包。其中,推荐使用npm安装依赖包,原因如下: 兼容性更广:npm是Node.js的默认包管理工具,具有更高的兼容性。社区支持:npm拥有更大的用户基础和社区支持,…...
如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库教程
简介 本教程将向你介绍如何在 Ubuntu 22.04 上安装 Cassandra NoSQL 数据库。 Apache Cassandra 是一个分布式的 NoSQL 数据库,旨在处理跨多个普通服务器的大量数据,并提供高可用性,没有单点故障。Apache Cassandra 是一个高度可扩展的分布…...
leetcode 面试经典 150 题:轮转数组
链接轮转数组题序号189题型数组解法1. 额外数组法,2. 原数组翻转法(三次翻转法)难度中等熟练度✅✅✅✅ 题目 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
