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

冒泡排序解析


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

相关推荐
阿旭超级学得完13 分钟前
C++11包装器(function和bind)
java·开发语言·c++·算法·哈希算法·散列表
掉鱼的猫1 小时前
Spring AI 2.0 GA 倒计时:先别急,来看看 Java AI 框架的另一条路
java·openai·agent
Refrain_zc1 小时前
Android 应用内 APK 安装全方案:从静默安装到普通安装的详解
java
正儿八经的少年2 小时前
Spring Boot 两种激活配置方式的作用与区别
java·spring boot·后端
云烟成雨TD2 小时前
Spring AI Alibaba 1.x 系列【52】Interrupts 中断机制:节点执行前后静态中断
java·人工智能·spring
疯狂成瘾者2 小时前
Spring Boot 项目中的 SMTP 邮件验证码服务技术解析
java·spring boot·后端
y = xⁿ2 小时前
Java并发八股学习日记
java·开发语言·学习
xifangge20252 小时前
【深度排障】从 OS 底层寻址剖析 javac 不是内部或外部命令 核心报错:变量空间隔离与自动化部署终极范式
java·开发语言·jdk·自动化
肖恩想要年薪百万2 小时前
JSP中常用JSTL标签
java·开发语言·状态模式