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

冒泡排序解析


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]严格大于才交换,相等的元素不会交换位置,所以相对顺序保持不变。

相关推荐
盐水冰2 小时前
MybatisPlus
java·mybatisplus
SunnyDays10112 小时前
使用 Java 提取和删除 PDF 文档附件(完整指南)
java·pdf
Stack Piston2 小时前
Spring实践@Cacheable坑
java·后端·spring
二宝1522 小时前
互联网大厂Java面试实战演练:谢飞机的三轮提问与深入解析
java·spring boot·redis·微服务·面试·kafka·oauth2
陌上花开zz2 小时前
Spring Boot整合EasyExcel,动态导出表头和数据
java·spring boot·easyexcel·动态导出
MicoZone2 小时前
源码-redisson
java
happymaker06262 小时前
请求头 & 文件下载 & JSP 内置对象实战
java·前端·servlet
Cosmoshhhyyy2 小时前
《Effective Java》解读第46条:优先选择Stream中无副作用的函数
java·windows·python
无籽西瓜a2 小时前
【西瓜带你学设计模式 | 第十一期 - 模板方法模式】模板方法模式 —— 流程骨架与钩子实现、优缺点与适用场景
java·后端·设计模式·软件工程·模板方法模式