冒泡排序:像煮汤一样让数字「冒泡」

🔥「炎码工坊」技术弹药已装填!

点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】


一、问题驱动:为什么需要冒泡排序?

场景描述

假设你是一家奶茶店的店员,每天营业结束后需要将20杯奶茶的销量数据按从小到大排序,以便统计热门款。如果手动排序效率低,如何用代码快速解决?

核心矛盾

  • 数据量小(20个数),不需要复杂算法
  • 需要直观、易实现的方案(新手友好)
  • 稳定性要求高(相同销量的奶茶不能乱序)

冒泡排序正是这种场景下的理想选择:简单、稳定、无需额外空间。


二、冒泡排序原理:煮汤的比喻

冒泡排序就像煮一锅汤:

  1. 搅拌动作:相邻元素两两比较(像气泡碰撞)
  2. 大气泡上浮:每轮遍历将当前最大值移动到数组末尾
  3. 重复加热:直到所有元素有序

算法步骤(以 [5, 3, 8, 1] 为例)

  1. 第1轮:找出最大值 8

    复制代码
    [5,3,8,1] → [3,5,8,1] → [3,5,8,1] → [3,5,1,8]  
  2. 第2轮:找出次大值 5

    复制代码
    [3,5,1,8] → [3,5,1,8] → [3,1,5,8]  
  3. 第3轮:找出第三大值 3

    复制代码
    [3,1,5,8] → [1,3,5,8]  

三、Java代码实现(JDK 17)

复制代码
import java.util.Arrays;

public class BubbleSort {
    // 基础版冒泡排序
    public static void bubbleSort(int[] arr) {
        boolean swapped; // 标记是否发生交换
        for (int i = 0; i < arr.length - 1; i++) {
            swapped = false;
            // 每轮减少一个已排序的元素
            for (int j = 0; j < arr.length - 1 - i; 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;
        }
    }

    // 鸡尾酒排序(双向冒泡)
    public static void cocktailSort(int[] arr) {
        int start = 0;
        int end = arr.length - 1;
        boolean swapped = true;

        while (swapped) {
            swapped = false;

            // 从左到右:找最大值
            for (int i = start; i < end; i++) {
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i + 1);
                    swapped = true;
                }
            }
            if (!swapped) break;
            end--; // 缩小右边界

            // 从右到左:找最小值
            for (int i = end; i > start; i--) {
                if (arr[i] < arr[i - 1]) {
                    swap(arr, i, i - 1);
                    swapped = true;
                }
            }
            start++; // 缩小左边界
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] sales1 = {5, 3, 8, 1};
        bubbleSort(sales1);
        System.out.println("基础版排序结果: " + Arrays.toString(sales1)); // 输出: [1, 3, 5, 8]

        int[] sales2 = {2, 3, 4, 5, 6, 7, 8, 1};
        cocktailSort(sales2);
        System.out.println("鸡尾酒排序结果: " + Arrays.toString(sales2)); // 输出: [1, 2, 3, 4, 5, 6, 7, 8]
    }
}

四、方案对比:如何选择实现方式?

实现方案 时间复杂度(平均) 空间复杂度 稳定性 适用场景
基础版 O(n²) O(1) 稳定 教学演示、小型数据集
优化版 O(n²)~O(n) O(1) 稳定 数据部分有序的情况
鸡尾酒排序 O(n²) O(1) 稳定 需双向优化的极端场景

优化点说明

  • 基础版缺陷:即使数据已有序,仍会进行所有轮次比较
  • 优化版改进 :通过 swapped 标志提前终止无效遍历(如输入 [1,2,3,4,5] 时仅需1轮遍历)
  • 鸡尾酒排序:双向遍历(先找最大后找最小),适合「部分有序但两端混乱」的数据

鸡尾酒排序实战案例

以数组 [2,3,4,5,6,7,8,1] 为例:

  1. 基础版冒泡排序 :需要 7轮 遍历才能将 1 移动到最前
  2. 鸡尾酒排序 :仅需 3轮 即可完成排序
    • 第1轮:从左到右将 8 移动到末尾,从右到左将 1 移动到最前
    • 第2轮:处理中间未排序部分 [2,3,4,5,6,7]
    • 第3轮:验证已完全有序

五、可视化流程图


六、专有名词说明表

术语 英文全称 解释说明
冒泡排序 Bubble Sort 通过相邻元素交换实现的排序算法
时间复杂度 Time Complexity 衡量算法运行时间随输入规模增长的趋势
空间复杂度 Space Complexity 衡量算法所需额外存储空间的指标
稳定性 Stability 相同元素排序后相对位置是否改变
鸡尾酒排序 Cocktail Shaker Sort 双向冒泡排序,交替从头尾开始比较
优化标志 Swap Flag 判断是否提前终止排序的布尔变量
最后交换位置 Last Swap Index 记录最后一次交换的位置以缩小遍历范围

总结:冒泡排序是学习排序算法的「Hello World」,虽然效率不如快速排序,但在小型数据集和教学场景中仍有价值。掌握其核心思想(两两比较、逐轮冒泡)是理解更复杂算法的基石。对于部分有序的数据(如奶茶店销量数据),鸡尾酒排序能显著减少遍历次数,是值得尝试的优化方案。

🚧 您已阅读完全文99%!缺少1%的关键操作:

加入「炎码燃料仓」

🚀 获得:

√ 开源工具红黑榜 √ 项目落地避坑指南

√ 每周BUG修复进度+1%彩蛋

(温馨提示:本工坊不打灰工,只烧脑洞🔥)

相关推荐
张先shen15 分钟前
Elasticsearch RESTful API入门:全文搜索实战(Java版)
java·大数据·elasticsearch·搜索引擎·全文检索·restful
天河归来1 小时前
springboot框架redis开启管道批量写入数据
java·spring boot·redis
张先shen1 小时前
Elasticsearch RESTful API入门:全文搜索实战
java·大数据·elasticsearch·搜索引擎·全文检索·restful
codervibe1 小时前
如何用 Spring Security 构建无状态权限控制系统(含角色菜单控制)
java·后端
codervibe1 小时前
项目中如何用策略模式实现多角色登录解耦?(附实战代码)
java·后端
TCChzp1 小时前
synchronized全链路解析:从字节码到JVM内核的锁实现与升级策略
java·jvm
大葱白菜1 小时前
🧩 Java 枚举详解:从基础到实战,掌握类型安全与优雅设计
java·程序员
笑衬人心。1 小时前
在 Mac 上安装 Java 和 IntelliJ IDEA(完整笔记)
java·macos·intellij-idea
SimonKing1 小时前
颠覆传统IO:零拷贝技术如何重塑Java高性能编程?
java·后端·程序员
sniper_fandc2 小时前
SpringBoot系列—MyBatis(xml使用)
java·spring boot·mybatis