11.3 冒泡排序

目录

11.3   冒泡排序

11.3.1   算法流程

11.3.2   效率优化

11.3.3   算法特性


11.3   冒泡排序

冒泡排序(bubble sort)通过连续地比较与交换相邻元素实现排序。这个过程就像气泡从底部升到顶部一样,因此得名冒泡排序。

如图 11-4 所示,冒泡过程可以利用元素交换操作来模拟:从数组最左端开始向右遍历,依次比较相邻元素大小,如果“左元素 > 右元素”就交换二者。遍历完成后,最大的元素会被移动到数组的最右端。

bubble_operation_step7

图 11-4   利用元素交换操作模拟冒泡

11.3.1   算法流程

设数组的长度为 𝑛 ,冒泡排序的步骤如图 11-5 所示。

  1. 首先,对 𝑛 个元素执行“冒泡”,将数组的最大元素交换至正确位置
  2. 接下来,对剩余 𝑛−1 个元素执行“冒泡”,将第二大元素交换至正确位置
  3. 以此类推,经过 𝑛−1 轮“冒泡”后,前 𝑛−1 大的元素都被交换至正确位置
  4. 仅剩的一个元素必定是最小元素,无须排序,因此数组排序完成。

冒泡排序流程

图 11-5   冒泡排序流程

示例代码如下:

bubble_sort.c

/* 冒泡排序 */
void bubbleSort(int nums[], int size) {
    // 外循环:未排序区间为 [0, i]
    for (int i = size - 1; i > 0; i--) {
        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
        for (int j = 0; j < i; j++) {
            if (nums[j] > nums[j + 1]) {
                int temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
            }
        }
    }
}

11.3.2   效率优化

我们发现,如果某轮“冒泡”中没有执行任何交换操作,说明数组已经完成排序,可直接返回结果。因此,可以增加一个标志位 flag 来监测这种情况,一旦出现就立即返回。

经过优化,冒泡排序的最差时间复杂度和平均时间复杂度仍为 𝑂(𝑛2) ;但当输入数组完全有序时,可达到最佳时间复杂度 𝑂(𝑛) 。

bubble_sort.c

/* 冒泡排序(标志优化)*/
void bubbleSortWithFlag(int nums[], int size) {
    // 外循环:未排序区间为 [0, i]
    for (int i = size - 1; i > 0; i--) {
        bool flag = false;
        // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
        for (int j = 0; j < i; j++) {
            if (nums[j] > nums[j + 1]) {
                int temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
                flag = true;
            }
        }
        if (!flag)
            break;
    }
}

11.3.3   算法特性

  • 时间复杂度为 𝑂(𝑛2)、自适应排序:各轮“冒泡”遍历的数组长度依次为 𝑛−1、𝑛−2、…、2、1 ,总和为 (𝑛−1)𝑛/2 。在引入 flag 优化后,最佳时间复杂度可达到 𝑂(𝑛) 。
  • 空间复杂度为 𝑂(1)、原地排序:指针 𝑖 和 𝑗 使用常数大小的额外空间。
  • 稳定排序:由于在“冒泡”中遇到相等元素不交换。

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

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

相关文章

数据的表示和运算

目录 一.各进制间的相互转换 1.各进制转化为10进制 2.二进制和八进制&#xff0c;十六进制之间地相互转化 3.十进制转换为其他进制 二.BCD码&#xff08;Binary-Coded Decimal&#xff0c;用二进制编码的十进制&#xff09; 1.8421码 2.余3码 3.2421码 三.无符号整数 …

SpringMVC枚举类型字段处理

在日常的项目开发中经常会遇到一些取值范围固定的字段&#xff0c;例如性别、证件类型、会员等级等&#xff0c;此时我们可以利用枚举来最大程度减少字段的乱定义&#xff0c;统一管理枚举的值。 SpringMVC中对于枚举也有默认的处理策略&#xff1a; 对于RequestParam&#xf…

【用Python画画】六一儿童节画爱心

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、代码示例三、知识点梳理四、总结 一、前言 本文介绍如何使用Python的海龟画图工具turtle&#xf…

Redis 线程模型

Redis 线程模型 背景简介Redis 单线程客户端发起 Redis 请求命令的工作原理单线程面临的挑战及问题 Redis 多线程Redis v4.0 多线程命令Redis v6.0 多线程网络模型 总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术…

DNS设置(linux)

1.配置dns需要现在/etc/sysconfig/network-scripts/目录下的ifcfg-ens33(后面数字也可能是其他的)中配置DNS 2.编辑/etc/resolv.conf文件&#xff0c;将上面网卡中加的dns服务器ip添加到此文件 vi /etc/resolv.conf重启网络配置 service network restart常用的dns的ip 国内…

Flutter-自定义可展开文本控件

Flutter 在移动开发中&#xff0c;常常需要处理一些长文本显示的场景&#xff0c;如何优雅地展示这些文本并允许用户展开和收起是一个常见的需求。在本文中&#xff0c;我将分享如何使用Flutter实现一个可展开和收起的文本控件。 效果 我们将实现一个可展开和收起的文本控件…

JVM学习-详解类加载器(二)

双亲委派机制 双亲委派优势 避免类的重复加载&#xff0c;确保一个类的全局唯一性 Java类随着它的类加载器一起具备了一种带有优先级的层次关系&#xff0c;通过这种层次关系可以避免类的重复加载&#xff0c;当父类已经加载了该类&#xff0c;就没有必要子ClassLoader再加载…

Three.js——tween动画、光线投射拾取、加载.obj/.mtl外部文件、使用相机控制器

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

低代码开发平台(Low-code Development Platform)的模块组成部分

低代码开发平台&#xff08;Low-code Development Platform&#xff09;的模块组成部分主要包括以下几个方面&#xff1a; 低代码开发平台的模块组成部分可以按照包含系统、模块、菜单组织操作行为等维度进行详细阐述。以下是从这些方面对平台模块组成部分的说明&#xff1a; …

计算机系统结构之FORK和JOIN

程序语言中用FORK语句派生并行任务&#xff0c;用JOIN语句对多个并发任务汇合。 FORK语句的形式为FORK m&#xff0c;其中m为新领程开始的标号。 JOIN语句的形式为JOIN n&#xff0c;其中n为并发进程的个数。 例1&#xff1a;给定算术表达式ZEA*B*C/DF经并行编译得到如下程序…

什么是 Redis 缓存?它解决了什么问题?怎么使用它?

前言 写在前面&#xff0c;让我们从 3 个问题开始今天的文章&#xff1a;什么是 Redis 缓存&#xff1f;它解决了什么问题&#xff1f;怎么使用它&#xff1f; 在笔者近 3 年的 Java 一线开发经历中&#xff0c;尤其是一些移动端、用户量大的互联网项目&#xff0c;经常会使用…

数学建模 —— 层次分析法(2)

目录 一、层次分析法&#xff08;AHP&#xff09; 二、构造比较判断矩阵 2.1 两两比较法 三、单准则下的排序及一致检验 3.1 单准则下的排序 3.2 一致性检验 四、层次总排序 4.1 层次总排序的步骤 4.2 总排序一致性检验 一、层次分析法&#xff08;AHP&#xff09; 方…

Centos 7部署NTP

介绍 NTP是Network Time Protocol&#xff08;网络时间协议&#xff09;的简称&#xff0c;它是用来通过互联网或局域网将计算机时钟同步到世界协调时间&#xff08;UTC&#xff09;的协议。 安装 # yum安装 yum install -y ntp# 离线安装 #下载地址&#xff1a;https://mir…

Caliburn.Micro框架学习笔记——多页面处理案例

在聊这个之前&#xff0c;我们先来看一个静态类 在 Caliburn.Micro 中&#xff0c;ViewLocator 是一个用于查找和关联视图与视图模型的静态类。默认情况下&#xff0c;它根据约定&#xff08;命名约定或其他规则&#xff09;自动找到与视图模型相对应的视图。然而&#xff0c;…

【5】MySQL数据库备份-XtraBackup - 全量备份

MySQL数据库备份-XtraBackup-全量备份 前言环境版本 安装部署下载RPM 包二进制包 安装卸载 场景分析全量备份 | 恢复备份恢复综合 增量备份 | 恢复部分备份 | 恢复 前言 关于数据库备份的一些常见术语、工具等&#xff0c;可见《MySQL数据库-备份》章节&#xff0c;当前不再重…

【普通切换】【DC-based handover】【DAPS】协议栈分析

移动网络切换 移动通信中切换是保证终端业务的基本流程&#xff0c;而切换时延是终端(UE)不能与任何基站交互(传递)用户面数据包的最短时间。 在5G(NR)网络中当终端(UE)接收到切换命令时&#xff0c;将断开与源小区的连接向目标小区发起随机接入过程。在此期间终端(UE)的数据传…

深入理解linux文件系统与日志分析12

一、inode和block 文件是存储在硬盘上&#xff0c;硬盘上的最小存储单位是扇区&#xff0c;每个扇区的大小是512字节。 inode&#xff1a;存储元信息&#xff08;文件的属性--权限、创建者、创建日期等等&#xff09; block&#xff1a;块 连续的八个扇区组成一个块&#xf…

rpmbuild多进程批量编译脚本

脚本用法 使用手册 bash spec.sh --help Please ensure the directory ~/rpmbuild exists, And the script can execute in any directory.Usage: bash spec.sh [OPTION]... [*.spec]... [OPTION]...or: bash spec.sh [*.spec]... [OPTION]... [*.spec]... rpmbuild all sp…

【原型模式】详解

一.概念 原型模式是一种创建型设计模式&#xff0c;它的主要思想是通过复制现有对象来创建新对象&#xff0c;而不是通过实例化一个类来创建。在原型模式中&#xff0c;我们称被复制的对象为原型&#xff08;Prototype&#xff09;&#xff0c;新创建的对象为克隆体&#xff0…

【OpenHarmony】TypeScript 语法 ③ ( 条件语句 | if else 语句 | switch case 语句 )

文章目录 一、条件语句1、if else 语句2、switch case 语句 参考文档 : <HarmonyOS第一课>ArkTS开发语言介绍 一、条件语句 1、if else 语句 TypeScript 中的 if 语句 / if else 语句 用法 , 与 JavaScript 语言中的 if 语句 / if else 语句 语法 基本相同 ; if else 语…