排序——冒泡排序(Bubble sort)

2023-11-05

定义

冒泡排序是一种较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

算法原理

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

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

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

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

动画演示

假设我们有一个数列,初始值为[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],使用冒泡排序过程如下图所示。

从这个动画过程中,我们可以看到:

第一次冒泡排序完成后,最大值50到达数列的最右边。

第二次冒泡排序完成后,次大值48到达数列的次右边。

以此类推。

算法分析

关键字比较次数记为C,记录移动次数记为M。

时间复杂度

假设数列本身是正序的,那么一趟扫描即完成排序。C_{min}=n-1M_{min}=0。所需的那么最好的时间复杂度为O(n)

假设数列本身是反序的,需要n-1趟排序,每趟排序要进行n-i次关键字比较(i\leqslant i\leqslant n-1)1\leqslant i\leqslant n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这个情况下,比较和移动次数均达到最大值:C_{max}=\frac{n\ast (n-1)}{2}=O(n^{2})M_{max}=\frac{3\ast n\ast (n-1)}{2}=O(n^{2})。所需的那么最坏的时间复杂度为O(n^{2})

综上所述,冒泡排序总的平均时间复杂度为O(n^{2})

空间复杂度

每次移动记录的时候,需要一个附件的空间。所以,冒泡排序的空间复杂度为O(1)

算法稳定性

冒泡排序算法是稳定的。

因为,冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变。

代码实现

C语言

#define ARR_LEN 255 /*数组长度上限*/
#define elemType int /*元素类型*/

void bubbleSort (elemType arr[], int len) {
    elemType temp;
    for (int i=0; i<len-1; i++) {
        /* 外循环为排序趟数,len个数进行len-1趟 */
        for (int j=0; j<len-1-i; j++) { 
            /* 内循环为每趟比较的次数,第i趟比较len-i次 */
            if (arr[j] > arr[j+1]) { 
                /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

C++

using namespace std;
template<typename T>
//整数或浮点数皆可使用
void bubble_sort(T arr[], int len) {
    T temp;
    for (int i = 0; i < len - 1; i++) {
        for (int 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;
            }
        }
    }
}

Python3

def bubble_sort(nums):
    for i in range(len(nums) - 1):  # 这个循环负责设置冒泡排序进行的次数
        for j in range(len(nums) - i - 1):  # j为列表下标
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
    return nums

JAVA

public static void bubbleSort(int []arr) {
    for(int i =1;i<arr.length;i++) { 
        for(int j=0;j<arr.length-i;j++) {
            if(arr[j]>arr[j+1]) {
                int temp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }    
    }
}

算法掌握要求

在OI比赛或者程序设计中,必须掌握冒泡算法,因为这是最简单、最基本的排序算法。

例题

题目链接

http://47.110.135.197/problem.php?id=1035

题目

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入

有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。

输出

一个数据,是最少的旋转次数。

样例输入

4
4 3 2 1

样例输出

6

题目分析

从题目可知,就是查找逆序对。输入为4 3 2 1,可以知道,逆序对有(4, 3)、(4, 2)、(4, 1)、(3, 2)、(3, 1)和(2, 1),合计一共6对,所以答案为6。

解决方案

可以利用冒泡排序,对输入数据进行排序,记录调整顺序的次数,即为本题结果。

数据集

由于本题是一个模板题,所以数据量比较小,大小为1,000。使用冒泡排序,时间复杂度为O(n^{2}),可以完成任务。

如果数据集进一步扩大,那么冒泡排序就力不从心了,主要是因为时间复杂度太大,必须使用时间复杂度为O(nlogn)的稳定排序算法,比如归并排序。

参考代码

#include <bits/stdc++.h>
using namespace std;

int bubble_sort(T arr[], int len) {
    int ans = 0;
    for (int i = 0; i < len - 1; i++) {
        for (int j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                ans++;
            }
        }
    }
    return ans;
}

const int MAXN = 1e3;
int data[MAXN] = {};

int main() {
    int n;
    cin >> n;
    
    for (int i=0; i<n; i++) {
        cin >> data[i];
    }

    cout << bubble_sort(data, n) << endl;

    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

排序——冒泡排序(Bubble sort) 的相关文章

  • Bubble冒泡排序

    原谅我偷懒 是真的没有什么写的内容了啊 我都好怀疑他们那些大佬是怎么那么多的文章和技术分享的 我要自闭了 时间复杂度O n2 C 的内置排序函数使用的并非冒泡而是快排 Git地址 public override void SortOrder
  • 基于Lua的冒泡排序算法实现

    冒泡排序核心 比较相邻的元素 如果第一个比第二个大 就交换他们两个 对每一对相邻元素作同样的工作 从开始第一对到结尾的最后一对 这步做完后 最后的元素会是最大的数 针对所有的元素重复以上的步骤 除了最后一个 持续每次对越来越少的元素重复上面
  • 冒泡排序 例题:给出一组数将这组数按从小到大的顺序输出出来

    冒泡排序 例题 给出一组数将这组数按从小到大的顺序输出出来 学习笔记 方便自己日后复习 也可供大家参考学习 冒泡排序百度上是这样定义的 冒泡排序 它重复的走访过要排序的元素列 依次比较两个相邻元素 如果他们的顺序 如从大到小 首字母从A到Z
  • 【BZOJ 4069】 [Apio2015]巴厘岛的雕塑

    4069 apio2015 巴厘岛的雕塑 Time limit 1000 ms Memory limit 65536 KB Description The province of Bali has many sculptures locat
  • 【BZOJ】【P1816】【Cqoi2010】【扑克牌】【题解】【水题】

    传送门 http www lydsy com JudgeOnline problem php id 1816 一张图表示我wa了三次的心情 Code include
  • 【SGU 176】 Flow construction

    176 Flow construction time limit per test 0 5 sec memory limit per test 4096 KB input standard output standard You have
  • leetcode1921.消灭怪物的最大数量(中等)

    解法 排序 贪心 具体 计算出每个怪物到达城市的时间 然后排序 class Solution public int eliminateMaximum vector
  • 排序——冒泡排序(Bubble sort)

    定义 冒泡排序是一种较简单的排序算法 它重复地走访过要排序的元素列 依次比较两个相邻的元素 如果顺序 如从大到小 首字母从Z到A 错误就把他们交换过来 走访元素的工作是重复地进行直到没有相邻元素需要交换 也就是说该元素列已经排序完成 这个算
  • 排序算法之时间复杂度为O(N^2)的算法

    背景知识 排序算法算是比较基础的算法了 但是在面试过程中偶尔也会被问到 虽然很多语言都内置了排序函数 例如php的sort函数等等 但是还是有必要聊聊排序算法 这篇文章中将介绍时间复杂度为O N 2 的几个排序算法 本文基于从小到大排序讲解
  • JavaScript 实现 -- 冒泡排序

    文章目录 冒泡排序 代码实现 冒泡排序过程 时间复杂度 算法稳定性 冒泡排序 冒泡排序 Bubble Sort 也叫气泡排序 泡沫排序 是一种比较简单的排序算法 它通过遍历数组 比较相邻的两个元素 如果前一个元素比后一个元素大 则交换它们的
  • 【THOI 2012】 水位

    A1363 水位 思路题 做这道题的时候如果思路清晰的话 就是一道简单的乘法原理 高精度题 按照原始高度升序排序 最开始 所有点各自属于一个连通块 按照高度顺序 从最低的开始合并连通块 假设当前处理到 l r l r这个区间 他们的高度都是
  • java实现冒泡排序+图解冒泡排序+代码实现+代码解析(java)

    基本介绍 冒泡排序 Bubble Sorting 的基本思想是 通过对待 排序序列从前向后 从下标较小的元素开始 依次比较 相邻元素的值 若发现逆序则交换 使值较大 的元素逐渐从前移向后部 就象水底下的气泡一样逐渐 向上冒 由于上面的栗子举
  • 一不小心就弄懂了 冒泡,选择,插入,希尔,归并和快速排序

    今天我们主要看一些简单的排序 常见的时间复杂度 常数阶 1 对数阶 log2n 线性阶 n 线性对数阶 nlog2n 平方阶 n 立方阶 n K次方阶 n k 指数阶 2 n 常见的时间复杂度对应图 1 log2n n nlog2n n n
  • ★【动态规划】【线段树】基站选址

    问题描述 有N个村庄坐落在一条直线上 第i i gt 1 个村庄距离第1个村庄的距离为Di 需要在这些村庄中建立不超过K个通讯基站 在第i个村庄建立基站的费用为Ci 如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站 那么就成它被覆盖
  • 顺序表的冒泡排序算法及二分法查找代码实现

    本文主要实现了比较经典的冒泡排序算法 对已经有序或者基本有序的顺序表复杂度大大降低 和二分法查找 各位看官看代码吧 冒泡排序算法及二分法查找 include stdio h typedef struct int key SSTable El
  • C++实现——排序算法总结

    常见的排序算法有 直接插入 希尔 冒泡 快速 选择 堆排序 归并 基数 下面一一分析 并实现 1 冒泡排序 冒泡排序是最简单的排序算法 冒泡排序的基本思想是从后往前 或从前往后 两两比较相邻元素的值 若为逆序 则交换它们 直到序列比较完毕
  • 冒泡排序--数组的简单排序,从大到小,从小到大

    冒泡排序 是计算机程序中较为常见和简单的排序算法 它需要重复地走访需要进行排序的元素列 按照一定顺序依次比较两个相邻的元素 如果顺序错误就把他们交换过来 示意原图如下 我们需要的结果示意图如下 那我们应该怎么进行程序的编写才能满足这样的结果
  • CSP-J (NOIP普及组) 历年复赛真题考察内容(1998~2021)

    TZOJ题目分类 本博客原文地址 https www cnblogs com BobHuang p 14522022 html 其中 1 较简单题26题左右 2 动态规划17题 其中9题较好做 3 模拟 阅读题目将问题抽象建模写出程序 为1
  • 冒泡排序和鸡尾酒排序

    传统冒泡排序 import java util Arrays author 新新 ClassName BubbleSort Description 冒泡排序 date 2022年03月17日 public class BubbleSort1
  • 各类排序算法的比较总结

    排序算法是最基本最常用的算法 不同的排序算法在不同的场景或应用中会有不同的表现 我们需要对各种排序算法熟练才能将它们应用到实际当中 才能更好地发挥它们的优势 今天 来总结下各种排序算法 下面这个表格总结了各种排序算法的复杂度与稳定性 各种排

随机推荐

  • 用struts框架+正则表达式对数据进行校验

    创建文件名为XXX xxx validation xml XXX为Action类名 xxx为struct xml中对应的action配置的name名 并和该类放在同一个包中 校验文件部分代码如下 非字段型校验器
  • cesium 实现中文搜索定位

    cesium 实现根据中文搜索定位 天了噜 修改一下哦 高德地图获取的经纬度需要转一下哦 它是由偏移的啦 不是标准gps坐标 有接口 自行翻阅API 思路 利用高德的中文定位搜索获取选中定位的经纬度 cesium进行3D锚点定位 准备 申请
  • C语言 递归——n皇后

    递归算法 递归 递归的作用 n皇后 题目 代码 结果 递归 一个函数自己调用自己 递归和普通函数调用一样都是用栈来实现的 递归的作用 代替多重循环 将问题分解为规模更小的子问题再求解 解决本来就是用递归形式定义的问题 n皇后 题目 输入整数
  • 使用TortoiseGit操作分支的创建与合并

    第一步 创建本地分支 点击右键选择TortoiseGit 选择Create Branch 在Branch框中填写新分支的名称 若选中 switch to new branch 则直接转到新分支上 省去第二步 点击OK按钮 第二步 通过 Sw
  • 近阶段学习总结

    工作日志 要养成写工作日志的习惯 记录下每天的学习情况 包括新学的知识和每天的收获 要对每天新学的知识加以总结 让每一天的时间不至于白费 一定要总结 当天学到的新的知识点 尤其要反复更新和学习 才能举一反三 要专注于自己的事情 不要为外界的
  • 关于在使用Exchange2003系统时无法向sina,yahoo,hotmail等邮箱发送邮件问题的解决方法...

    先说普通的解决方法 转发 如果这些方法您已经用过还没有解决问题 请看本文章最后部分 该问题是由于反垃圾邮件软件引起的 已经和sina 确认过 他们最近部署了一套反垃圾邮件的系统在默认条件下 邮件服务器在发出helo命令与远端的邮件服务器通过
  • Nginx二级域名代理二级目录

    背景 今天做私单遇到一个很棘手的问题 甲方购买的是阿里云虚拟主机 众所周知虚拟主机虽然能绑定多个域名 但是只能指定一个根目录 也就是所有域名的访问都是指向到根目录 一共是开发了PC端 WAP端 管理端三个段 都要部署上去 用的vue cli
  • @Cacheable设置过期时间

    链接 https mp csdn net mp blog creation editor spm 1001 2101 3001 5352
  • Android开发者跳槽指南灵魂拷问

    前言 2020年是转折的一年 上半年疫情原因 很多学android开发的小伙伴失业了 虽找到了一份工作 但高不成低不就 下半年金九银十有想法更换一份工作 很多需要大厂面试经验和大厂面试真题的小伙伴 想提前准备刷下题 接下来分享一份我的字节跳
  • 907. 子数组的最小值之和

    907 子数组的最小值之和 原始题目链接 https leetcode cn problems sum of subarray minimums 给定一个整数数组 arr 找到 min b 的总和 其中 b 的范围为 arr 的每个 连续
  • 智能分类

    1 人工智能与机器学习 1 1 谈谈人工智能 人工智能 Artificial Intelligence 英文缩写为AI 它是研究 开发用于模拟 延伸和扩展人的智能的理论 方法 技术及应用系统的一门新的技术科学 人工智能是计算机科学的一个分支
  • GPS模块编程之NMEA0183协议

    NMEA 0183是美国国家海洋电子协会 National Marine Electronics Association 为海用电子设备制定的标准格式 现在已经成为GPS导航设备统一的RTCM Radio Technical Commiss
  • JSON parse error: Illegal unquoted character ((CTRL-CHAR, code 9))问题解决

    项目场景 周末在家看了公司最近上的新需求和相关代码 项目是SpringBoot框架 接口是POST类型的 问题描述 这个POST接口入参实体中有个String类型的属性rule 我在APIFox通过POST请求并debug这个接口的时候出现
  • 【Unity】ScriptableObject的介绍

    Unity ScriptableObject的介绍 看了下ScriptableObject的一些介绍 最大的优势感受有三点 json 把数据真正存储在了资源文件中 能够像其余资源那样管理它 例如退出运行也同样会保持修改 能够在项目之间很好的
  • 爬虫框架Scrapy(12)爬取动态页面

    文章目录 爬取动态页面 一 Splash 渲染引擎 1 render html 端点 2 execute 端点 3 常用属性与方法 1 Splash 对象的属性 2 Splash 对象的方法 二 安装 Scrapy Scrapy 1 安装
  • Java集合框架及基本接口

    文章目录 Collection接口及迭代器 泛型方法的使用 集合基本接口和实现 List ArrayList LinkedList ListIterator接口和Iterable接口的区别 Set HashSet TreeSet Queue
  • 统计字符串中整数个数

    输入一个字符串 内有数字和非数字字符 例如 jh2515da555adad22 dsd55252aa 将其中连续数字作为一个整数 依次存放在 一组数a中 例如 2515放在a 0 555放在a 1 统计有多少个整数 并输出这些数 inclu
  • Python中的物体检测算法有哪些?

    人工智能技术在不断发展 物体检测技术在计算机领域也变得越来越重要 提到人工智能 一定少不了Python Python语言的应用范围也逐渐广泛 那么你知道Python物体检测技术是什么吗 以下是详细的内容 什么是物体检测技术 物体检测技术 顾
  • Android——recyclerview.adapter公共方法、类、接口的作用简述

    功能分类 公共内部接口 使用场景 数据绑定 onCreateViewHolder ViewGroup parent int viewType onBindViewHolder VH holder int position getItemCo
  • 排序——冒泡排序(Bubble sort)

    定义 冒泡排序是一种较简单的排序算法 它重复地走访过要排序的元素列 依次比较两个相邻的元素 如果顺序 如从大到小 首字母从Z到A 错误就把他们交换过来 走访元素的工作是重复地进行直到没有相邻元素需要交换 也就是说该元素列已经排序完成 这个算