冒泡排序的面试话术和写法解析

冒泡排序解析


1. 面试话术

"冒泡排序是一种基础的比较排序算法。它的核心思想是相邻元素两两比较,如果顺序不对就交换,每一轮都会把当前未排序部分中最大的元素像气泡一样'浮'到末尾。

具体来说,我会用两层循环来实现:外层循环 控制总共需要进行多少轮冒泡,一个长度为 n 的数组,最多需要 n-1 轮;内层循环负责在每一轮中做相邻元素的比较和交换,并且每轮结束后,末尾已经有一个元素就位了,所以内层循环的范围可以逐渐缩小。

另外,我会加一个优化 :用一个布尔变量 swapped 来记录本轮有没有发生交换,如果一轮下来没有任何交换,说明数组已经有序了,可以提前退出,这样对近似有序的数组能把最好情况的时间复杂度优化到 O(n)。


2. Java 代码详解

java 复制代码
public class BubbleSort {

    public static void bubbleSort(int[] arr) {

        // 先拿到数组长度,后面会频繁用到
        int n = arr.length;

        // ====== 外层循环 ======
        // 外层循环控制"总共要冒几轮"
        // 每轮结束,最大的元素就像气泡一样浮到了末尾
        // n 个元素最多需要 n-1 轮,所以 i 从 0 到 n-2
        for (int i = 0; i < n - 1; i++) {

            // 【优化点】这个 flag 用来判断本轮有没有发生交换
            // 如果本轮一次交换都没发生,说明数组已经完全有序
            // 可以直接 break,不用再继续后面的轮次了
            boolean swapped = false;

            // ====== 内层循环 ======
            // 内层循环负责在本轮中,对"未排序区间"做相邻比较
            // 为什么上界是 n - 1 - i ?
            // 因为经过第 i 轮之后,末尾 i 个元素已经排好了
            // 它们是"已排序区",不需要再碰了,所以每轮少比较一次
            for (int j = 0; j < n - 1 - i; j++) {

                // 比较相邻的两个元素
                // 如果前面的比后面的大,说明顺序错了,需要交换
                // 这就是"冒泡"的核心动作:大的往右走
                if (arr[j] > arr[j + 1]) {

                    // 经典三步换:借助临时变量 temp 完成交换
                    // 直接 arr[j] = arr[j+1] 会把 arr[j] 原来的值丢掉
                    // 所以必须先用 temp 把它存起来
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;

                    // 发生了交换,把 flag 标记为 true
                    swapped = true;
                }
            }

            // 本轮结束后检查 flag
            // 如果 swapped 依然是 false,说明整轮没有任何交换
            // 数组已经有序,直接提前退出,不用再浪费时间了
            if (!swapped) {
                break;
            }
        }
    }

    // ====== 主函数:验证一下效果 ======
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};

        System.out.print("排序前: ");
        printArray(arr);

        bubbleSort(arr);

        System.out.print("排序后: ");
        printArray(arr);
    }

    // 辅助函数:打印数组
    static void printArray(int[] arr) {
        for (int val : arr) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}

📌 运行结果

复制代码
排序前: 64 34 25 12 22 11 90 
排序后: 11 12 22 25 34 64 90 

📌 手动模拟一遍(以 [5, 3, 1, 4] 为例)

轮次 过程 结果
第 1 轮 (5,3)换→(5,1)换→(5,4)换 [3, 1, 4, 5]5 到位
第 2 轮 (3,1)换→(3,4)不换 [1, 3, 4, 5]4 到位
第 3 轮 (1,3)不换 → swapped=false 提前退出

📌 关键变量总结

变量 类型 作用
n int 数组长度
i int 外层轮次计数,同时代表末尾已排好的元素个数
j int 内层遍历下标,用来比较 arr[j]arr[j+1]
swapped boolean 优化标志,本轮是否发生过交换
temp int 交换时的临时变量,防止值被覆盖

📌 复杂度分析

情况 时间复杂度 说明
最坏情况 O(n²) 数组完全逆序,每轮都要交换到底
平均情况 O(n²) 两层循环嵌套决定的
最好情况 O(n) 数组已经有序,第一轮没有交换,swapped 优化直接退出
空间复杂度 O(1) 只用了 tempswapped 等几个固定变量,原地排序

分析过程 :外层循环最多跑 n-1 次,内层循环第 i 轮跑 n-1-i 次,总比较次数 = (n-1) + (n-2) + ... + 1 = n(n-1)/2 ,所以是 O(n²)


📌 冒泡排序的稳定性

冒泡排序是稳定排序

因为我们的判断条件是 arr[j] > arr[j+1]严格大于才交换,相等的元素不会交换位置,所以相对顺序保持不变。

相关推荐
SL_staff15 分钟前
从RBAC到场景化授权:《无忧·企业文档》三级权限模型的技术实践解析
java·开源·产品
传奇开心果编程1 小时前
【springboot基础语法学与练】第 1 课:从零开始
java·spring boot·后端·学习
SL_staff1 小时前
财务系统慎用低代码?从数据模型闭环看合规落地的技术实践
java·低代码·全栈
滕州市燕猫虎计算机科技工作室个体工商户1 小时前
IDEA:Command line is too long
java·ide·intellij-idea
步行cgn2 小时前
Spring p 命名空间注入详解
java·前端·spring
YatHinLay2 小时前
MyBatis 流式查询实战:ResultHandler 处理海量数据
java
天天被压力2 小时前
【跨市场数据实战 #08】可转债折价机会怎么筛:3个接口抓比价、列表和实时盘口
java·人工智能·python
张某布响丸辣3 小时前
附件下载的安全边界:路径白名单、NAS 哨兵文件与 Redis Lua 一次性令牌
java·redis·redis lua·nas哨兵
YatHinLay3 小时前
Spring Boot + Calcite 实现跨库查询
java
酷炫码神4 小时前
MosMos 创意效果与能力边界展示
java