【算法基础】冒泡排序算法 - JAVA
一、算法基础
1.1 什么是冒泡排序
冒泡排序是一种简单直观的比较排序算法。它重复地走访待排序的数列,依次比较相邻两个元素,如果顺序错误就交换它们,直到没有元素需要交换为止。
1.2 基本思想
- 比较相邻元素:从头开始,两两比较相邻元素
- 交换位置:如果前一个元素大于后一个元素,则交换位置
- 重复操作:每完成一次迭代,最大的元素会"冒泡"到数组末尾
- 多次迭代:重复以上步骤,每次排除已排好序的末尾元素
1.3 时间复杂度
- 最好情况:O(n),当数组已经排好序
- 最坏情况:O(n²),当数组逆序排列
- 平均情况:O(n²)
二、冒泡排序的分类
2.1 标准冒泡排序
标准版本每次将最大元素冒泡到末尾:
- 外层循环:控制排序轮数,最多n-1轮
- 内层循环:控制每轮比较次数,逐渐减少
- 无优化:即使数组已排序仍会执行全部循环
2.2 优化冒泡排序
通过标记变量检测一轮比较中是否有交换发生:
- 设置标记:初始假设本轮无交换
- 发生交换:更新标记变量
- 提前终止:若一轮比较无交换发生,则排序完成
三、冒泡排序实现
3.1 标准实现
public class BubbleSort {/*** 标准冒泡排序算法* @param arr 待排序数组*/public static void bubbleSort(int[] arr) {int n = arr.length;// 外层循环控制排序轮数for (int i = 0; i < n - 1; i++) {// 内层循环进行相邻元素比较和交换// 每轮结束后,最大的i+1个元素已经排好序for (int j = 0; j < n - i - 1; j++) {// 如果当前元素大于下一个元素,交换它们if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}
3.2 优化实现
public class OptimizedBubbleSort {/*** 优化版冒泡排序算法* @param arr 待排序数组*/public static void bubbleSort(int[] arr) {int n = arr.length;boolean swapped;// 外层循环控制排序轮数for (int i = 0; i < n - 1; i++) {swapped = false;// 内层循环进行相邻元素比较和交换for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;// 标记发生了交换swapped = true;}}// 如果没有发生交换,说明数组已经有序,提前结束if (!swapped) {break;}}}
}
3.3 双向冒泡排序(鸡尾酒排序)
public class CocktailSort {/*** 双向冒泡排序(鸡尾酒排序)算法* @param arr 待排序数组*/public static void cocktailSort(int[] arr) {int left = 0;int right = arr.length - 1;boolean swapped;while (left < right) {swapped = false;// 从左向右,将最大元素冒泡到右侧for (int i = left; i < right; i++) {if (arr[i] > arr[i + 1]) {int temp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = temp;swapped = true;}}// 如果没有交换,数组已经有序if (!swapped) {break;}right--; // 最大元素已经到位,缩小右边界swapped = false;// 从右向左,将最小元素冒泡到左侧for (int i = right; i > left; i--) {if (arr[i] < arr[i - 1]) {int temp = arr[i];arr[i] = arr[i - 1];arr[i - 1] = temp;swapped = true;}}// 如果没有交换,数组已经有序if (!swapped) {break;}left++; // 最小元素已经到位,缩小左边界}}
}
四、算法分析与优化
4.1 理论推导
冒泡排序的工作原理可以用以下数学表达式描述:
- 比较次数:(n-1) + (n-2) + ... + 1 = n(n-1)/2
- 最大交换次数:同上 n(n-1)/2
- 元素移动次数:最多3×n(n-1)/2(每次交换需要3次移动)
4.2 优化策略
- 提前终止优化:如前述,检测是否有交换发生
- 记录最后交换位置:每轮记录最后一次交换的位置,下一轮只需扫描到该位置即可
- 奇偶交替扫描:类似鸡尾酒排序,减少"乌龟"(小元素靠后)的情况
public class EnhancedBubbleSort {/*** 记录最后交换位置的优化冒泡排序* @param arr 待排序数组*/public static void bubbleSort(int[] arr) {int n = arr.length;int lastSwappedIndex = n - 1;int newLastSwappedIndex;while (lastSwappedIndex > 0) {newLastSwappedIndex = 0;for (int i = 0; i < lastSwappedIndex; i++) {if (arr[i] > arr[i + 1]) {// 交换元素int temp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = temp;// 记录最后交换的位置newLastSwappedIndex = i;}}// 更新下一轮排序的终止位置lastSwappedIndex = newLastSwappedIndex;}}
}
五、完整示例程序
public class BubbleSortDemo {public static void main(String[] args) {// 测试数据int[] arr = {64, 34, 25, 12, 22, 11, 90};System.out.println("原始数组: ");printArray(arr);// 执行优化版冒泡排序optimizedBubbleSort(arr);System.out.println("\n排序后数组: ");printArray(arr);}/*** 优化的冒泡排序实现*/public static void optimizedBubbleSort(int[] arr) {int n = arr.length;boolean swapped;for (int i = 0; i < n - 1; i++) {swapped = false;for (int j = 0; j < n - i - 1; j++) {// 如果当前元素大于下一个元素,交换它们if (arr[j] > arr[j + 1]) {swap(arr, j, j + 1);swapped = true;}}// 如果没有发生交换,数组已经有序if (!swapped) {System.out.println("提前结束于第 " + (i + 1) + " 轮");break;}}}/*** 交换数组中两个元素*/private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}/*** 打印数组*/private static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}
}
六、总结
冒泡排序是一种经典的排序算法,其特点如下:
6.1 优点
- 实现简单:代码直观易懂,适合教学使用
- 稳定性好:相等元素不会改变相对顺序
- 原地排序:不需要额外空间
- 自适应性:对于部分有序数据效率较高
6.2 缺点
- 效率低下:平均时间复杂度为O(n²)
- 比较次数多:即使数据已经有序,基本版本仍需大量比较
6.3 适用场景
- 小规模数据:元素数量较少时表现尚可
- 教学演示:算法思想简单直观
- 接近有序数据:优化版本在这种情况下效率较高
冒泡排序虽然在大规模数据中效率不高,但其思想简单,实现容易,是学习排序算法的良好起点。在实际应用中,可根据数据特性选择更高效的排序算法,如快速排序、归并排序等。
相关文章:
【算法基础】冒泡排序算法 - JAVA
一、算法基础 1.1 什么是冒泡排序 冒泡排序是一种简单直观的比较排序算法。它重复地走访待排序的数列,依次比较相邻两个元素,如果顺序错误就交换它们,直到没有元素需要交换为止。 1.2 基本思想 比较相邻元素:从头开始…...
Nginx搭建test服务器
创建test域名 进入阿里云添加解析 创建域名:test.xxxxx.com 服务器复制项目代码 新建目录,Git拉取项目代码,安装上插件包 修改配置文件,启动测试服务 修改配置文件“服务器接口” 开启服务pm2 start app.js --name "t…...
依赖倒置原则
当然可以!这次我们来详细讲解 依赖倒置原则(DIP: Dependency Inversion Principle),它是 SOLID 五大设计原则中的压轴,也是最关键的“架构型原则”。 我将从: 什么是依赖倒置原则(定义&#x…...
PostgreSQL 的 VACUUM 与 VACUUM FULL 详解
PostgreSQL 的 VACUUM 与 VACUUM FULL 详解 一、基本概念对比 特性VACUUMVACUUM FULL定义常规维护操作,清理死元组激进重组操作,完全重写表数据锁级别不阻塞读写(共享锁)排他锁(阻塞所有操作)空间回收只标记空间为可用,不返还OS空间返还操作…...
SQL面试题——留存分析之使用bitmap 计算留存
使用bitmap 计算留存 之前我们说过,留存分析其实在企业数据分析中,是很基础但是也很重要的,留存分析可以反映产品的发展是否健康,是否可持续发展,之前我们介绍过,可以看看之前的文章 SQL面试题——留存分析 因为使用工具的限制,所以我们实现方式也会有所不同,之前我们…...
P2415集合求和 题解
P2415 集合求和 题解 公式推导: 设集合有 n 个元素,记为 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an。 每个子集要么包含某个元素,要么不包含。 我们固定某个元素 a k a_k ak,再从剩下的 n − 1 n -…...
【2025年五一数学建模竞赛】C题 完整论文 模型建立与求解
目录 2025年五一数学建模竞赛 C题完整论文:建模与求解 Matlab代码一、问题重述二、模型假设与符号说明2.1 模型基本假设2.2 符号说明 问题一:预测博主新增关注数问题二:预测用户的新关注行为问题三:预测用户在线状态及互动博主问题…...
wpf 输入框 在输入时去除水印
wpf ScrollViewer 在输入数据时去除水印 在WPF(Windows Presentation Foundation)中,ScrollViewer控件通常用于显示滚动内容。如果你想在ScrollViewer中使用数据输入(例如文本输入),并且希望在输入时去除水…...
数字智慧方案5857丨智慧机场解决方案与应用(53页PPT)(文末有下载方式)
资料解读:智慧机场解决方案与应用 详细资料请看本解读文章的最后内容。 随着科技的飞速发展,智慧机场的建设已成为现代机场发展的重要方向。智慧机场不仅提升了旅客的出行体验,还极大地提高了机场的运营效率。本文将详细解读沃土数字平台在…...
C语言-指针(二)
一级指针 一级指针指的是存储了变量地址的指针 一级指针的变量类型是 类型 * 一级指针的类型与变量的类型有些不同 例:int * p 前面的int * 是该地址的类型 int a 0; int * p a; 这里的指针 p 就是一级指针 二级指针 指针变量也是变量因此也会有地…...
React 组件prop添加类型
给函数的props做注解 import { useState } from reacttype Props { className:string,title?:string } // 自定义一个Button组件 function Button(props:Props){// 解构出classname\const {className} propsreturn <button className{className}>点击我</button&g…...
Spring Boot中集成Guava Cache或者Caffeine
一、在Spring Boot(1.x版本)中集成Guava Cache 注意: Spring Boot 2.x用户:优先使用Caffeine,性能更优且维护活跃。 1. 添加依赖 在pom.xml中添加Guava依赖: <dependency><groupId>com.google.guava</groupId&…...
全感官交互革命:当 AI 大模型学会 “看、听、说、创”
引言:从 “文字对话” 到 “全感官体验”,AI 正在重塑人类认知边界 当 AI 不再局限于文本对话,而是能 “看懂” 图像、“听懂” 语音、“生成” 视频,并将这些模态无缝融合时,一场关于人机交互的革命已然开启。DeepSe…...
Linux 库文件详解
Linux 库文件详解 一、库文件概述 库文件是预先编译好的方法的集合,它为程序员提供了一种方便的方式来复用代码。在 Linux 系统中,主要有两种类型的库文件:静态库和共享库。 静态库(.a 文件) 使用静态库࿰…...
蒙特卡罗方法(Monte Carlo Method):基于随机采样的数值计算与模拟技术
核心思想 蒙特卡罗方法通过随机采样和统计模拟解决数学、物理、工程等领域的复杂问题,其核心是利用大数定律——当样本量足够大时,样本均值会收敛于期望值。 关键特点: 无维度诅咒&#x…...
HTTPS协议:更安全的HTTP
目录 1. 前言 2. HTTP 与 HTTPS:安全的分水岭 2.1 HTTP 的安全隐患 2.2 HTTPS 的安全提升 3. HTTPS 的核心概念 3.1 加密三剑客:对称加密、非对称加密与哈希算法 3.2 SSL/TLS 握手过程:建立安全通道的关键步骤 3.3 数字证书ÿ…...
Flutter BottomNavigationBar 详解
目录 一、引言 二、BottomNavigationBar 的基本用法 三、主要属性 1. 基本配置 2. 导航项配置 3. 导航类型选择 四、高级功能实现 1. 结合 PageView 实现滑动切换 2. 添加徽章提示 3. 自定义凸起按钮(FAB融合) 4. 渐变背景实现 五、自定义 B…...
吴恩达深度学习作业 RNN模型——字母级语言模型
一. 简单复习一下RNN RNN RNN适用于处理序列数据,令是序列的第i个元素,那么就是一个长度为的序列,NLP中最常见的元素是单词,对应的序列是句子。 RNN使用同一个神经网络处理序列中的每一个元素。同时,为了表示序列的…...
数字时代,如何为个人信息与隐私筑牢安全防线?
首席数据官高鹏律师团队编著 在当今数字化时代,个人信息和隐私保护至关重要。我们在享受数字生活带来的便利时,也面临着个人信息泄露、隐私被侵犯的风险。下面将从先进技术和法律途径两个方面,探讨如何严格保护个人信息和隐私。 一、先进技…...
javascript交换值最好三种
代码 1. 位运算(性能高,但只能用于整数) var a15; var b32; console.log(a) //15 console.log(b) //32 a a ^ b; b a ^ b; a a ^ b; console.log(a) //32 console.log(b) //152. 数组结构(性能高,但要ES6) var a15; var b32; console.log(…...
C++-Lambda表达式
目录 1.什么是 Lambda? 2.例子:打印每个元素(和 for_each 一起用) 3.捕获外部变量(Capture) 3.1. 捕获值(拷贝):[] 3.2. 捕获引用:[&] 3.3. 指定捕…...
逻辑回归的多分类实战:以鸢尾花数据集为例
文章目录 引言:从二分类到多分类一、多分类问题无处不在二、One-vs-All策略揭秘1. 核心思想2. 数学表达 三、鸢尾花分类完整实现1. 环境准备2. 数据加载与探索3. 数据预处理4. 模型训练与评估5. 决策边界可视化 四、关键参数解析五、总结 引言:从二分类到…...
[面试]SoC验证工程师面试常见问题(一)
SoC验证工程师面试常见问题(一) 摘要:在面试 SoC 验证工程师职位时,面试官通常会重点考察候选人对 SystemVerilog 和 UVM (Universal Verification Methodology) 的掌握程度,因为这两者是现代 IC 验证的核心技能。以下是可能会被问到的常见问题,涵盖 SystemVerilo…...
传统银行服务和 区块链支付无缝融合的一种解决方案
Dragonfly Capital 的合伙人 Alex Pack 曾表示:“DeFi 的目标是重构全球银行体系,并打造开放且无须许可的经营环境。”在 DeFi 的金融世界中,加密资产架构在区块链上,通过各个协议实现资产之间的高效转移和价值的实时流通,如 Metamask 钱包的自托管,Uniswap 的资产交易,…...
大语言模型能力评定探讨
有标准答案的评估(选择题) 评估语言模型能力的基本思路是准备输入和标准答案,比较不同模型对相同输入的输出 由于AI答题有各种各样答案,因此现在是利用选择题考察。 有一个知名的选择题的基准叫做Massive Multitask Language Und…...
解构区块链身份认证:从ID到零知识证明的实战指南
引言 在数字经济高速发展的今天,数字身份已成为个人与数字世界交互的核心凭证。传统中心化身份系统存在数据孤岛、隐私泄露、单点故障等痛点,而区块链技术凭借去中心化、不可篡改、可追溯的特性,为数字身份验证提供了革命性解决方案…...
IntelliJ IDEA 使用教程
文章目录 一、创建项目二、创建模块三、创建包四、创建类五、编写代码六、运行代码注意 一、创建项目 二、创建模块 【File】->【New】->【Module…】 三、创建包 【helloword】->【右击 src】->【New】->【Package】 四、创建类 【helloword】->【s…...
HBM的哪些事
命令操作 这也许是DDR往HBM演进的一些奇淫技巧。 本篇内容属于杂谈,关于HBM的奇淫技巧,随后出专题介绍。...
C++ std::initializer_list 详解
std::initializer_list 是 C11 引入的一个轻量级模板类,用于支持花括号初始化列表({1, 2, 3})的语义。它允许函数或构造函数接受任意长度的同类型初始化列表,是实现统一初始化({} 语法)的核心组件。 1. 基本…...
网络原理 - 13(HTTP/HTTPS - 4 - HTTPS)
目录 HTTPS 是什么 不得不的策略 - 应对“运营商劫持” “加密” 是什么 分类 对称加密 非对称加密 HTTPS 工作原理 1)引入对称加密 2) 引入非对称加密 中间人攻击 引入证书 证书的验证过程 完! HTTPS 是什么 HTTPS 也是一个应…...
当MCP撞进云宇宙:多芯片封装如何重构云计算的“芯“未来?
当MCP撞进云宇宙:多芯片封装如何重构云计算的"芯"未来? 2024年3月,AMD发布了震撼业界的MI300A/B芯片——这颗为AI计算而生的"超级芯片",首次在单封装内集成了13个计算芯片(包括3D V-Cache缓存、CDNA3 GPU和Zen4 CPU),用多芯片封装(Multi-Chip Pac…...
Kotlin Flow流
一 Kotlin Flow 中的 stateIn 和 shareIn 一、简单比喻理解 想象一个水龙头(数据源)和几个水杯(数据接收者): 普通 Flow(冷流):每个水杯来接水时,都要重新打开水龙头从…...
虚拟局域网(VLAN)实验(Cisco Packet Tracer)-路由器、交换机的基本配置
好的,我们来根据你提供的文档,一步步地在 Cisco Packet Tracer 中完成这个跨交换机划分 VLAN 的实验。 实验目标: 配置两台交换机 SW1 和 SW2,划分 VLAN 10 和 VLAN 20,配置 Trunk 链路,并测试同 VLAN 和跨 VLAN 的连…...
【论文速递】2025年09周 (Robotics/Embodied AI/LLM)
目录 LLM-Microscope:揭示标点符号在Transformers的上下文中的隐藏作用英文摘要中文摘要 SurveyX:通过大型语言模型实现学术调查自动化英文摘要中文摘要 数学推理的自我奖励校正英文摘要中文摘要 VideoGrain:调整时空关注以进行多元透明视频编…...
自主机器人模拟系统
一、系统概述 本代码实现了一个基于Pygame的2D自主机器人模拟系统,具备以下核心功能: 双模式控制:支持手动控制(WASD键)和自动导航模式(鼠标左键设定目标) 智能路径规划:采用改进型…...
DeepSeek构建非农预测模型:量化关税滞后效应与非线性经济冲击传导
AI分析:非农数据前瞻与关税影响的滞后性 根据AI模型对多维度经济指标的交叉验证,4月非农就业报告或呈现“增速放缓但未失速”的特征。当前市场共识预期为新增就业13.3万人(前值22.8万),失业率维持4.2%,时薪…...
前端面经-VUE3篇--vue3基础知识(一)插值表达式、ref、reactive
一、计算属性(computed) 计算属性(Computed Properties)是 Vue 中一种特殊的响应式数据,它能基于已有的响应式数据动态计算出新的数据。 计算属性有以下特性: 自动缓存:只有当它依赖的响应式数据发生变化时ÿ…...
云原生后端架构的优势与最佳实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 在过去的几年里,随着云计算和容器化技术的迅猛发展,云原生架构逐渐成为现代企业和开发团队构建和运维应用系统的首选方式。云原生架构通过高度的自动化、弹性伸缩、微服务化等特点,使得企业能够在不断变化…...
力扣838.推多米诺随笔
“生活就像海洋,只有意志坚强的人,才能到达彼岸。”—— 马克思 题目 n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。 每过一秒,倒向左边的多米诺骨牌会推动其左侧…...
aab转apk
一、 android34升级: 1、升级到安卓34(蓝牙、图片) 再蓝牙广播的地方加入Context.RECEIVER_EXPORTED 2、废弃了 BluetoothAdapter#enable() 和 BluetoothAdapter#disable(),需要修改 // 以前的蓝牙操作BluetoothManager bluetoo…...
LeetCode 560. 和为 K 的子数组 | 前缀和与哈希表的巧妙应用
文章目录 方法思路:前缀和 哈希表核心思想关键步骤 代码实现复杂度分析示例解析总结 题目描述 给定一个整数数组 nums 和一个整数 k,请统计并返回该数组中和为 k 的子数组的数量。 子数组是数组中连续的非空元素序列。 示例 输入:nums …...
【Hive入门】Hive性能调优:小文件问题与动态分区合并策略详解
目录 引言 1 Hive小文件问题概述 1.1 什么是小文件问题 1.2 小文件产生的原因 2 Hive小文件合并机制 2.1 hive.merge.smallfiles参数详解 2.2 小文件合并流程 2.3 合并策略选择 3 动态分区与小文件问题 3.1 动态分区原理 3.2 动态分区合并策略 3.3 动态分区合并流程…...
基于Springboot+Vue3.0的前后端分离的个人旅游足迹可视化平台
文章目录 0、前言1、前端开发1.1 登录注册页面1.2 首页1.3 足迹管理1.3.1 足迹列表1.3.2 添加足迹1.4 个人中心1.4.1 足迹成就1.4.2 个人信息1.4.3 我的计划2、后端开发2.1 用户接口开发2.2 足迹点接口2.3 旅游计划接口3、完整代码资料下载0、前言 项目亮点: 前端用户权限动态…...
安妮推广导航系统开心版多款主题网址推广赚钱软件推广变现一键统计免授权源码Annie
一、源码描述 这是一套推广导航源码(Annie),基于Funadmin框架(ThinkPHP8Layui ),内置多款主题,可以用于网址推广,或者用于软件推广,PC端软件手机端软件,后台…...
单片机-STM32部分:1、STM32介绍
飞书文档https://x509p6c8to.feishu.cn/wiki/CmpZwTgHhiQSHZkvzjdc6c4Yn1g STM32单片机不是一款芯片,而是一个系列的芯片? STM32系列单片机是ST(意法半导体)公司开发的一套32位微控制器基于Arm Cortex()-M处理器,它包…...
PHP-session
PHP中,session(会话)是一种在服务器上存储用户数据的方法,这些数据可以在多个页面请求或访问之间保持。Session提供了一种方式来跟踪用户状态,比如登录信息、购物车内容等。当用户首次访问网站时,服务器会创…...
php artisan resetPass 执行密码重置失败的原因?php artisan resetPass是什么 如何使用?-优雅草卓伊凡
php artisan resetPass 执行密码重置失败的原因?php artisan resetPass是什么 如何使用?-优雅草卓伊凡 可能的原因 命令不存在:如果你没有正确定义这个命令,Laravel 会报错而不是提示”重置密码失败”用户不存在:’a…...
AI大模型-微调和RAG方案选项
在搭建知识库的方向上,有两个落地方案:微调、RAG。两个方案的比对: 方案选型 微调 让大模型(LLM)去学习现有知识(调整大模型的参数,让它学习新的知识),最终生成一个新的…...
MySQL 第一讲---基础篇 安装
前言: 在当今数据驱动的时代,掌握数据库技术已成为开发者必备的核心技能。作为全球最受欢迎的开源关系型数据库,MySQL承载着淘宝双十一每秒50万次的交易请求,支撑着Facebook百亿级的数据存储,更是无数互联网企业的数据…...
【JavaScript-Day 1】从零开始:全面了解 JavaScript 是什么、为什么学以及它与 Java 的区别
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...