【十大排序算法】冒泡排序

news2024/11/27 7:22:13

在排序的大海上,冒泡排序像一朵花朵般绽放,
每个元素都像是水珠,跃动在涟漪的波浪中。
它们轻轻上浮,与周围的元素相比较,
若自身更大,便悄然交换位置。

这是一场缓慢的舞蹈,每一步都小心翼翼,
直到所有元素都找到了自己的位置,
像是夜空中闪烁的星星,它们最终静静地排列,
形成了一个美妙的序列,闪耀着排序的光芒。

文章目录

  • 一、冒泡排序的思想
  • 二、冒泡排序的发展历程
  • 三、冒泡排序具象化
  • 四、冒泡排序算法实现
  • 五、冒泡排序的效率优化
  • 六、冒泡排序的特性
  • 推荐阅读

一、冒泡排序的思想

冒泡排序的思想是通过依次比较相邻的元素,并将较大(或较小)的元素交换到右侧(或左侧),从而逐渐 “冒泡” 出最大(或最小)的元素。在每一轮排序中,都会选取一个相邻的元素对进行比较,并根据排序规则交换它们的位置,直到整个序列有序为止。这个过程像是气泡在液体中上浮一样,故得名 “冒泡排序”。

二、冒泡排序的发展历程

冒泡排序是一种经典的排序算法,其发展历程可以追溯到 20 世纪初。

  1. 最初的想法:冒泡排序的基本思想可能源自人们日常生活中对物品排序的经验。比如,在洗碗时,较重的碗会沉到水底,而较轻的碗则会浮到水面,类似于冒泡排序中较大的元素会逐渐“冒泡”到序列的顶端。
  2. 早期实现:冒泡排序最早的形式可能是手动进行的。人们可能会通过比较相邻的元素,并根据大小调整它们的位置,以达到排序的目的。
  3. 数学描述:对冒泡排序进行更严格的数学描述和分析可能出现在 20 世纪中期,随着计算机科学的发展和对算法的研究。
  4. 计算机实现:随着计算机的出现和普及,冒泡排序得到了实际的应用和实现。早期的计算机程序员可能会使用冒泡排序作为排序算法之一,因为它相对简单易懂。
  5. 算法改进:随着时间的推移,人们对排序算法进行了改进和优化。尽管冒泡排序的时间复杂度较高,但它仍然具有教学和理解的价值。同时,一些改进的冒泡排序算法也被提出,以减少其时间复杂度或优化其性能。

三、冒泡排序具象化

场景假设:我们需要将下图序列使用冒泡排序按从小到大进行排序。
workspace.png

  1. 1 1 1 轮冒泡:对当前序列执行冒泡,最终元素 5 5 5 交换至正确位置

workspace (1).png

  1. 2 2 2 轮冒泡:对当前序列执行冒泡,最终元素 4 4 4 交换至正确位置

workspace.png

  1. 3 3 3 轮冒泡:对当前序列执行冒泡,最终元素 3 3 3 交换至正确位置

workspace (1).png

  1. 4 4 4 轮冒泡:对当前序列执行冒泡,最终元素 2 2 2 交换至正确位置

workspace.png
n n n 个元素,只要 n − 1 n - 1 n1 个元素完成排序,最后一个元素必定处于正确的位置。

四、冒泡排序算法实现

void bubbleSort(int[] arr) {
    int n = arr.length; // 获取数组的长度

    // 外层循环控制比较轮数,每轮确定一个最大值
    for (int i = 0; i < n - 1; i++) { 

        // 内层循环控制每轮的比较次数
        for (int j = 0; j < n - i - 1; j++) { 
            if (arr[j] > arr[j + 1]) { // 如果当前元素大于下一个元素,则交换它们的位置
                // 交换 arr[j] 和 arr[j+1]
                int temp = arr[j]; // 使用临时变量 temp 存储 arr[j] 的值
                arr[j] = arr[j + 1]; // 将 arr[j+1] 的值赋给 arr[j]
                arr[j + 1] = temp; // 将 temp 中存储的 arr[j] 的值赋给 arr[j+1]
            }
        }
    }
}

算法时间复杂度分析:

情况时间复杂度计算公式公式解释
最好情况 O ( n ) O(n) O(n) T ( n ) = n = O ( n ) T(n) = n = O(n) T(n)=n=O(n)当输入的数据已经是有序的(升序或降序),冒泡排序只需要遍历一次数组,因此最优时间复杂度是 O ( n ) O(n) O(n)
平均情况 O ( n 2 ) O(n^2) O(n2) T ( n ) = ∑ i = 1 n i = n ( n + 1 ) 2 = O ( n 2 ) T(n) = \sum_{i = 1}^{n}i=\frac{n(n + 1)}{2}=O(n^2) T(n)=i=1ni=2n(n+1)=O(n2)在平均情况下,冒泡排序需要比较 n ( n + 1 ) 2 \frac{n(n + 1)}{2} 2n(n+1) 次,因此平均时间复杂度是 O ( n 2 ) O(n^2) O(n2)
最坏情况 O ( n 2 ) O(n^2) O(n2) T ( n ) = ∑ i = 1 n i = n ( n + 1 ) 2 = O ( n 2 ) T(n) = \sum_{i = 1}^{n}i=\frac{n(n + 1)}{2}=O(n^2) T(n)=i=1ni=2n(n+1)=O(n2)当输入的数据是完全逆序的,冒泡排序需要比较 n ( n + 1 ) 2 \frac{n(n + 1)}{2} 2n(n+1) 次,因此最坏时间复杂度是 O ( n ) O(n) O(n)

五、冒泡排序的效率优化

在之前的例子中,我们发现:其实,第 2 2 2 轮冒泡之后就已经排序好了。

仔细观察,我们可以发现一个规律:如果在某轮冒泡没有发生交换操作,则排序就已经完成

因此,我们可以优化冒泡排序:

/* 优化后的冒泡排序 */
void optimizedBubbleSort(int[] nums) {
    int n = nums.length;
    boolean swapped; // 标志位:记录是否发生了元素交换

    for (int i = 0; i < n - 1; i++) {
        swapped = false; // 每轮外循环开始前,将标志位重置为 false

        // 内循环:未排序区间为 [0, n-i-1]
        for (int j = 0; j < n - i - 1; j++) {
            if (nums[j] > nums[j + 1]) {
                // 交换 nums[j] 与 nums[j + 1]
                int temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
                swapped = true; // 记录发生了元素交换
            }
        }

        // 如果没有发生交换,则说明数组已经有序,直接跳出循环
        if (!swapped) {
            break;
        }
    }
}

六、冒泡排序的特性

冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,通过比较相邻元素并交换它们,使得每一轮遍历都能找到当前未排序部分的最大值(或最小值),从而逐步将其放到正确的位置上。冒泡排序的特性包括:

  1. 稳定性:冒泡排序是一种稳定的排序算法,即相同元素的相对位置在排序前后不会改变。
  2. 时间复杂度:在最坏情况下,冒泡排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中 n n n 是要排序的元素个数。在最好情况下(即已经有序),时间复杂度为 O ( n ) O(n) O(n)。平均情况下的时间复杂度也为 O ( n 2 ) O(n^2) O(n2)
  3. 空间复杂度:冒泡排序的空间复杂度为 O ( 1 ) O(1) O(1),因为它仅使用了常数级别的额外空间。
  4. 原地排序:冒泡排序是一种原地排序算法,它只需要常数级别的辅助空间来存储临时变量,而不需要额外的数据结构。
  5. 适用情况:由于冒泡排序的时间复杂度较高,通常不适用于大规模数据的排序,但在某些特定情况下(如数据基本有序的情况下),冒泡排序可能表现良好。

推荐阅读

  1. Spring 三级缓存
  2. 深入了解 MyBatis 插件:定制化你的持久层框架
  3. Zookeeper 注册中心:单机部署
  4. 【JavaScript】探索 JavaScript 中的解构赋值
  5. 深入理解 JavaScript 中的 Promise、async 和 await

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工作流】 工作流相关概念及Activiti基本介绍

目录 工作流作用工作流的几个要素应用具体应用场景 工作流系统工作流系统的组成部分&#xff1a;都有哪些工作流系统 工作流引擎工作流引擎的特点&#xff1a;都有哪些工作流引擎 工作流、工作流引擎、工作流系统三者区别ActivitiActiviti的主要特点发展历史优缺点优点&#xf…

【Linux操作系统】进程状态(1)

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; Linux &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解 Linux操作系统 进程状态 的相关内容。 如果看到最后您觉得这篇文章…

AXI Quad SPI IP核AXI4接口下的三种操作模式

当选择Enable Performance Mode选项时&#xff0c;AXI4接口包括在内。在该模式下&#xff0c;IP核可以在增强模式下操作&#xff08;未选择启用XIP模式&#xff09;或XIP模式&#xff08;选择启用XIP模式&#xff09;。在性能模式下&#xff0c;AXI4接口用于在DTR和DRR位置的突…

网络编程(UPD和TCP)

//发送数据 //UDP协议发送数据 package com.example.mysocketnet.a02UDPdemo;import java.io.IOException; import java.net.*;public class SendMessageDemo {public static void main(String[] args) throws IOException {//发送数据//1.创建DatagramSocket对象(快递公司)//…

机器学习-降维算法,PCK,LDA,NMF,LLE

目录 一:数据降维 二:PCA降维算法 1.概念 2.算法原理: 3.降维流程: 4.如何找到方差最大的方向 5.降维公式: 1.协方差和散度矩阵: 2.特征值分解矩阵原理 3.SVD分解矩阵原理 6.PCA算法的两种实现方法: 1.基于特征值分解协方差矩阵实现PCA算法 2. 基于SVD分解协…

面试成功的不二法门:详解Vue3答题章法

前言 面试题在网络上有如海洋之深&#xff0c;对于同一知识点&#xff0c;每个人的理解也各有千秋。我们在面试中常常会遇到一个瞬息间脑海里一片空白的情况&#xff0c;其实这并不是因为我们不懂&#xff0c;而是因为我们在回答的时候缺乏一个清晰的思路。那么问题来了&#x…

服务器远程连接工具有哪些?

【天联】是一款功能强大的服务器远程连接工具&#xff0c;它可以让用户通过网络远程连接到目标服务器&#xff0c;实现远程操作和管理。【天联】的使用场景非常广泛&#xff0c;特别适用于以下几个领域&#xff1a; 零售、收银软件应用的远程管理&#xff1a;【天联】可以结合医…

Ubuntu22.04之解决:terminal使用alt+1/alt+2/alt+3失效问题(二百三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

我的名字叫大数据: 第7章 我的自拍展

7.1 生活瞬间:通过数据图像呈现 数据健身达人们!在经过一系列的辛勤锻炼后,是时候来看看我的“自拍展”了。通过数据图像,我们不仅可以更直观地了解数据,还能将复杂的信息以简单而美观的方式呈现出来。在这一节中,我将带你领略各种数据图像的魅力,从色彩缤纷的条形图到…

C#之EntityFramework的应用

目录 1&#xff0c;名词概述。 2&#xff0c;实体数据模型EDM介绍。 3&#xff0c;规范函数。 4&#xff0c;查看Linq转换成的SQL语句。 5&#xff0c;数据的增删改查。 5.1&#xff0c;数据查询 5.2&#xff0c;数据插入 5.3&#xff0c;数据更新 5.4&#xff0c;数据…

go语言接口之接口值

概念上讲一个接口的值&#xff0c;接口值&#xff0c;由两个部分组成&#xff0c;一个具体的类型和那个类型的值。它们 被称为接口的动态类型和动态值。对于像Go语言这种静态类型的语言&#xff0c;类型是编译期的概 念&#xff1b;因此一个类型不是一个值。在我们的概念模型中…

MySQL-权限管理(二)

一 host中的含义 /usr/local/mysql/bin/mysql -pLXYlxy2:024.#8u} -S /data/mysql/tmp/mysqld.sock select user,host,authentication_string from mysql.user; %:主要允许从任何主机连接到MySQL服务器&#xff0c;即外部连接localhost: 代表只允许本地主机连接到MySQL服务器&…

spring boot2.7.x遇到问题

validation报错 高版本已移除了validation以来&#xff0c;需手动添加 <dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId> </dependency>mybatis报错 升级版本 <dependency>&…

07-指针的概念与引用,索引

指针的概念与引用&#xff0c;索引 一、内存地址 字节&#xff1a; 定义&#xff1a; 字节&#xff08;byte&#xff09;是内存容量的一个单位&#xff0c;一个字节包含8个位&#xff08;bit&#xff09;。 地址&#xff1a; 定义&#xff1a; 内存地址是系统为了方便区分…

物流装备企业太多,恶性竞争,2024年的新出路在哪里?

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 之前写过一篇文章&#xff0c;关于中国有N多家物流装备企业&#xff0c;从列表中可猜测&#xff0c;行业内竞争惨烈。可以点击查看此篇 中国物流…

当代中国获奖的知名作家信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;作家管理&#xff0c;作品管理&#xff0c;论坛管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0c;公告&#x…

上海亚商投顾:微盘股指数大跌超6% 全市场仅500余只个股上涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡调整&#xff0c;创业板指午后一度跌超1%&#xff0c;微盘股指数盘中跌逾7%&#xff0c;小市值个…

HTML+CSS+JS 动态展开式菜单

效果演示 实现了一个可展开菜单按钮的效果,点击按钮会弹出一个菜单列表,菜单列表中包含多个选项。按钮的样式为一个圆形背景,中间有三条横线,表示可以展开。当按钮被点击后,三条横线会变成一个叉号,表示可以收起。菜单列表的样式为一个白色背景,四周有阴影,包含多个选项…

【JavaEE】Spring Boot 日志详解

一 日志概述 日志是用于记录系统运行状态、用户操作和重大事件的工具。 1.日志的用途 系统监控 监控现在几乎是一个成熟系统的标配, 我们可以通过日志记录这个系统的运行状态, 每⼀个方法的响应时间, 响应状态等, 对数据进行分析, 设置不同的规则, 超过阈值时进行报警. 比如统…

数据库资源评估:构建高效数据架构的基础

前言 这篇文章主要是描述在平时开发的过程中怎么进行合理的资源评估&#xff0c;包括数据量预估、用户行为建模、资源预估、资源预览等等。 存储架构设计三步骤 性能估算步骤 用户预估常见方式 用户行为建模 存储性能需求计算 存储性能需求计算案例 案例 用户行为模型:每天使…