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

算法基础一:冒泡排序

一、冒泡排序

1、定义

冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。

冒泡排序是所有排序算法中最简单、最易实现的算法,有时也称为起泡排序算法。

使用冒泡排序算法对 n 个数据进行排序,实现思路是:从待排序序列中找出一个最大值或最小值,这样的操作执行 n-1 次,最终就可以得到一个有序序列。
 

2、过程分析

举个例子,对 {14, 33, 27, 35, 10} 序列进行升序排序(由小到大排序),冒泡排序算法的实现过程是:

  • 从 {14, 33, 27, 35, 10} 中找到最大值 35;
  • 从 {14,33,27,10} 中找到最大值 33;
  • 从 {14, 27, 10} 中找到最大值 27;
  • 从 {14, 10} 中找到最大值 14。

由此,我们就得到了一个有序序列 {10, 14, 27, 33, 35}。

那么,如何从待排序序列中找到最大(或最小)的值呢?以找最大值为例,遍历待排序序列,过程中不断地比较相邻两个元素的值,如果后者比前者的值小就交换它们的位置。遍历完成后,最后一个元素就是当前待排序序列中最大的。

例如,从 {14, 33, 27, 35, 10} 中找到最大值 35 的过程如下:
1) 比较 14 和 33 的大小,显然后者更大,不需要交换它们的位置,序列不发生改变。

2) 比较 33 和 27 的大小,前者大于后者,交换它们的位置,新的序列如下图所示。
 


3) 比较 33 和 35 的大小,后者更大,不需要交换它们的位置,序列不发生改变。
 


4) 比较 35 和 10 的大小,前者大于后者,交换它们的位置,新的序列如下图所示。
 


可以看到,序列中值最大的元素 35 被移动到了序列的末尾。整个查找最大值的过程中,最大的元素就像水里的气泡一样,一点一点地“冒”了出来,这也是将该算法命名为冒泡排序算法的原因。

采用同样的方法,我们可以很轻松地从 {14, 27, 33, 10} 中找到最大值 33。找到 33 后的新序列为:
 


从 {14, 27, 10} 中找到最大值 27 后,新的序列如下图所示:
 


从 {14, 10} 中找到最大值 14 后,新的序列如下图所示:
 

所有比 10 大的数都被一一找到,所以 10 必然是最小的数,这也是为什么“对 n 个数据进行排序,找最大值的过程只重复 n-1 次”的原因。

3、代码实现

如下是用冒泡排序算法对 { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70} 完成升序排序的C语言程序:
#include <stdio.h>
//函数声明
void Bubble_sort(int arr[], int len);int main(void)
{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);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}void Bubble_sort(int arr[], int len)
{for (int i = 0; i < len - 1; i++)//循环次数(n - 1){for (int j = 0; j < len - i - 1; j++){//每次循环的两两比较元素if (arr[j] > arr[j + 1])//如果前一个数大于后一个,就把大的给往后放{int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
如下是用冒泡排序算法对 {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70} 完成升序排序的 Python 程序:
#待排序序列
list =  [22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70]
def Bubble_sort():#序列中有 n 个元素,就遍历 n-1 遍for i in range(len(list-1)):#从第 1 个元素开始遍历,比那里至 len(list)-1-ifor j in range(len(list)-1-i):#比较两个相邻元素的大小if list[j] > list[j+1]:#交换 2 个元素的位置list[j],list[j+1] = list[j+1],list[j]
Bubble_sort()
for i in list:print(i,end=" ")

二、双向冒泡排序

1、通过冒泡排序进阶:

先回忆一下普通的冒泡排序算法,比如对 {14, 33, 27, 35, 10} 进行升序排序,过程如下图所示:
 


                                                        图 1 普通的冒泡排序


从待排序序列的第一个元素开始,比较相邻元素的大小,找到最大(或最小)的元素并移动到序列的末尾。重复整个过程,最终就可以得到一个有序的序列。

双向冒泡排序算法对图 1 的排序过程进行了优化,接下来仍以 {14, 33, 27, 35, 10} 进行升序排序为例,带大家了解双向冒泡排序。

1) 最初的待排序序列是 {14, 33, 27, 35, 10},和普通的冒泡排序一样,从第一个元素 14 向后查找,通过相邻元素的比较,找到最大的元素并移动到序列的末尾,过程如下图所示:
 


                                                        图 2 第一轮从前向后冒泡


在图 2 的基础上,待排序序列变成了 {14, 27, 33, 10}。接下来从末尾元素 10 开始向前查找,通过相邻元素的比较,找到最小的元素并移动到序列的开头。
 


                                                                图 3 第一轮从后往前冒泡


经过了第 1 步,从元素 14 向后查找,找到了最大值 35;再从元素 10 向前查找,找到了最小值 10。最终,待排序序列变成了 {14, 27, 33}。

2) 采用和第 1 步相同的方法,从 {14, 27, 33} 中的第一个元素 14 开始向后查找,通过相邻元素的对比,最终可以找到最大值 33 并移动到序列的末尾,待排序序列变成了 {14, 27}。
 


                                                        图 4 第二轮从前往后冒泡


继续从 {14, 27} 中最后一个元素 27 开始向前查找,可以找到最小值 14 并移动到序列的开头,待排序序列变成了 {27}。
 


                                                                图 5 第二轮从后往前冒泡

3) 由于待排序序列 {27} 只有 1 个元素,不再需要冒泡排序,此时整个序列 {10, 14, 27, 33, 35} 就是一个升序序列。

2、代码实现

下面是使用双向冒泡排序对 { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 } 完成升序排序的C语言程序:
#include <stdio.h>// 函数声明
void bubble_sort(int arr[], int len);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]);  // 计算数组长度//insertion_sort(arr, len);  // 调用插入排序函数bubble_sort(arr, len);  // 调用插入排序函数// 打印排序后的数组for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}return 0;
}void bubble_sort(int arr[], int len)
{int i, temp;int low = 0, high = len -1;while (low < high){for (i = low; i < high;i++){if (arr[i] > arr[i + 1]){temp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = temp;}}high--;for (i = high; i > low; i--){if (arr[i] < arr[i - 1]){temp = arr[i];arr[i] = arr[i - 1];arr[i - 1] = temp;}}low++;}}
下面是使用双向冒泡排序对{ 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 } 完成升序排序的 Python 程序:
list = [22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70]  # 定义并初始化一个列表list
def Bubble_sort():temp,i = 0,0low, high = 0,len(list) -1while low<high:for i in range (low,high):if list[i] > list[i+1]:list[i],list[i+1] = list[i+1],list[i]high-=1for i in range (high,low,-1):if list[i] < list[i-1]:list[i], list[i-1] =list[i-1],list[i]low+=1Bubble_sort()
for i in list:print(i,end = " ")

相关文章:

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 …...

云开发实战教程:手把手教你高效开发应用

声明&#xff1a;本文仅供实践教学使用&#xff0c;没有任何打广告成分 目录 1.引言 2.云开发 Copilot介绍 云开发 Copilot 的功能与特点 3.环境准备 步骤一登录账号 步骤二新建环境 4.开发实践 4.1AI 生成低代码应用 4.2AI 生成低代码页面/区块 4.3AI 优化低代码组件…...

Git基本操作快速入门(30min)

Git基本操作快速入门&#xff08;30min&#xff09; 文章目录 Git基本操作快速入门&#xff08;30min&#xff09;1. 建立本地仓库2. 本地仓库链接到远端仓库3. 将本地仓库推送到远端4. Git常用命令 作为一名程序员&#xff0c;使用Github来进行代码的版本管理是必修课&#xf…...

VS Code AI开发之Copilot配置和使用详解

随着AI开发工具的迅速发展&#xff0c;GitHub Copilot在Cursor、Winsuf、V0等一众工具的冲击下&#xff0c;推出了免费版本。接下来&#xff0c;我将为大家介绍GitHub Copilot的配置和使用方法。GitHub Copilot基于OpenAI Codex模型&#xff0c;旨在为软件开发者提供智能化的代…...

QT中使用OpenGL function

1.前言 QT做界面编程很方便&#xff0c;QTOpenGL的使用也很方便&#xff0c;因为QT对原生的OpenGL API进行了面向对象化的封装。 如&#xff1a; 函数&#xff1a;initializeOpenGLFunctions()...... 类&#xff1a;QOpenGLVertexArrayObject、QOpenGLBuffer、QOpenGLShader…...

STM32-笔记16-定时器中断点灯

一、实验目的 使用定时器 2 进行中断点灯&#xff0c;500ms LED 灯翻转一次。 二&#xff0c;定时器溢出时间计算 Tout&#xff1a;定时器溢出时间 Ft&#xff1a;定时器的时钟源频率 ARR&#xff1a;自动重装载寄存器的值&#xff08;可设置ARR从0开始&#xff0c;但是计数到…...

Live555、FFmpeg、GStreamer介绍

Live555、FFmpeg 和 GStreamer 都是处理流媒体和视频数据的强大开源框架和工具&#xff0c;它们广泛应用于实时视频流的推送、接收、处理和播放。每个框架有不同的设计理念、功能特性以及适用场景。下面将详细分析这三个框架的作用、解决的问题、适用场景、优缺点&#xff0c;并…...

oracle基础:理解 Oracle SQL 中的 WHERE 后的 (+) 用法

在使用 Oracle 数据库进行 SQL 查询时&#xff0c;可能会遇到 WHERE 子句后带有 () 的语法。这是 Oracle 专有的外连接&#xff08;Outer Join&#xff09;表示法。虽然现代 SQL 标准推荐使用 LEFT JOIN 和 RIGHT JOIN 语法&#xff0c;但在某些遗留系统中&#xff0c;这种写法…...

【linux】进程间通信(IPC)——匿名管道,命名管道与System V内核方案的共享内存,以及消息队列和信号量的原理概述

目录 ✈必备知识 进程间通信概述 &#x1f525;概述 &#x1f525;必要性 &#x1f525;原理 管道概述 &#x1f525;管道的本质 &#x1f525;管道的相关特性 &#x1f525;管道的同步与互斥机制 匿名管道 &#x1f525;系统调用接口介绍 &#x1f525;内核原理 …...

【深度学习】卷积网络代码实战ResNet

ResNet (Residual Network) 是由微软研究院的何凯明等人在2015年提出的一种深度卷积神经网络结构。ResNet的设计目标是解决深层网络训练中的梯度消失和梯度爆炸问题&#xff0c;进一步提高网络的表现。下面是一个ResNet模型实现&#xff0c;使用PyTorch框架来展示如何实现基本的…...

org.apache.zookeeper.server.quorum.QuorumPeerMain

QuorumPeerMain源代码 package org.apache.zookeeper.server.quorum;import java.io.IOException; import javax.management.JMException; import javax.security.sasl.SaslException; import org.apache.yetus.audience.InterfaceAudience; import org.apache.zookeeper.audi…...

oscp学习之路,Kioptix Level2靶场通关教程

oscp学习之路&#xff0c;Kioptix Level2靶场通关教程 靶场下载&#xff1a;Kioptrix Level 2.zip 链接: https://pan.baidu.com/s/1gxVRhrzLW1oI_MhcfWPn0w?pwd1111 提取码: 1111 搭建好靶场之后输入ip a看一下攻击机的IP。 确定好本机IP后&#xff0c;使用nmap扫描网段&…...

SkyWalking java-agent 是如何工作的,自己实现一个监控sql执行耗时的agent

Apache SkyWalking 是一个开源的应用性能监控 (APM) 工具&#xff0c;支持分布式系统的追踪、监控和诊断。SkyWalking Agent 是其中的一个重要组件&#xff0c;用于在服务端应用中收集性能数据和追踪信息&#xff0c;并将其发送到 SkyWalking 后端服务器进行处理和展示。 SkyW…...

每天40分玩转Django:Django表单集

Django表单集 一、知识要点概览表 类别知识点掌握程度要求基础概念FormSet、ModelFormSet深入理解内联表单集InlineFormSet、BaseInlineFormSet熟练应用表单集验证clean方法、验证规则熟练应用自定义配置extra、max_num、can_delete理解应用动态管理JavaScript动态添加/删除表…...

查看vue的所有版本号和已安装的版本

1.使用npm查看Vue的所有版本&#xff1a; npm view vue versions2.查看项目中已安装的 Vue.js 版本 npm list vue...

钉钉h5微应用,鉴权提示dd.config错误说明,提示“jsapi ticket读取失败

这个提示大多是因为钉钉服务器没有成功读取到该企业的jsticket数据 1. 可能是你的企业corpid不对 登录钉钉管理后台 就可以找到对应企业的corpid 请严格使用这个corpid 。调用获取jsapi_ticket接口&#xff0c;使用的access_token对应的corpid和dd.config中传递的corpid不一致…...

【openGauss】正则表达式次数符号“{}“在ORACLE和openGauss中的差异

一、前言 正则作为一种常用的字符串处理方式&#xff0c;在各种开发语言&#xff0c;甚至数据库中&#xff0c;都有自带的正则函数。但是正则函数有很多标准&#xff0c;不同标准对正则表达式的解析方式不一样&#xff0c;本次在迁移一个ORACLE数据库到openGauss时发现了一个关…...

宏任务和微任务的区别

在 JavaScript 的异步编程模型中&#xff0c;宏任务&#xff08;Macro Task&#xff09;和微任务&#xff08;Micro Task&#xff09;是事件循环&#xff08;Event Loop&#xff09;机制中的两个重要概念。它们用于管理异步操作的执行顺序。 1. 宏任务 (Macro Task) 宏任务是较…...

数据库系统原理复习汇总

数据库系统原理复习汇总 一、数据库系统原理重点内容提纲 题型&#xff1a;主观题 1、简答题 第一章&#xff1a;数据库的基本概念&#xff1a;数据库、数据库管理系统、三级模式&#xff1b;两级映像、外码 第二章&#xff1a;什么是自然连接、等值连接&#xff1b; 第三…...

Linux day1204

五.安装lrzsz lrzsz 是用于在 Linux 系统中文件上传下载的软件。大家可能会存在疑问&#xff0c;我们用 MobaXterm 图形化界面就可以很方便的完成上传下载&#xff0c;为什么还要使用这个软件来 完成上传下载呢&#xff1f;实际上是这样的&#xff0c; Linux 的远程连接工具…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考

目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候&#xff0c;显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...