面试手写代码,第一题经常就是把数组从小到大排。很多人能立刻写出 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冒泡排序这道题,面试官盯的就是循环终止条件和边界,把这两处写对,比背代码本身值钱。