面试手写代码,第一题经常就是把数组从小到大排。很多人能立刻写出 java冒泡排序,可让讲讲内层边界为什么减一,或者问还能怎么优化,就卡住了。这道题考的恰恰是这些细节。
核心逻辑与完整代码
相邻两个元素比较,大的往后换,每一轮把当前最大值沉到末尾:
int[] a = {5, 3, 8, 1}; for (int i = 0; i < a.length - 1; i++) { boolean swapped = false; for (int j = 0; j < a.length - 1 - i; j++) { if (a[j] > a[j + 1]) { int t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; swapped = true; } } if (!swapped) break; }拿 {5, 3, 8, 1} 走一遍:第一轮 5 和 3 交换得 3,5,5 和 8 不动,8 和 1 交换,变成 3,5,1,8,最大值 8 沉底;第二轮 5 和 1 交换,变成 3,1,5;第三轮 3 和 1 交换,变成 1,3,排序结束。
两个必须讲清的细节
第 i 轮结束后,末尾 i 个元素已经就位,所以内层边界是 a.length - 1 - i,不减只是浪费比较次数,减错了才出 bug。swapped 标记负责提前退出:某一轮一次交换都没发生,说明已经有序,直接 break,本来就有序的数组一轮就结束,时间从 O(n²) 降到 O(n)。
新手常犯的错就三种:内层条件写成 j < a.length 导致数组越界;交换时忘存中间变量,两个位置互相覆盖;swapped 忘了在每轮开头重置,提前退出永远不生效。写完自己跑三个用例:空数组、单元素、全部相等的元素。
面试时的加分说法
- 平均和最坏时间复杂度 O(n²),最好 O(n),空间 O(1)
- 稳定排序,相等元素不交换,相对顺序保持不变
- 对比选择排序:每轮找最小值只交换一次,交换次数少,但不稳定
- 实际项目用 Arrays.sort(),数据量上万时冒泡明显吃力,它的价值在于理解排序思想
手写 java冒泡排序这道题,面试官盯的就是循环终止条件和边界,把这两处写对,比背代码本身值钱。