二分查找适用于已排序数组,时间复杂度O(log n),核心是每次比较中点并缩小一半范围;需注意边界控制、溢出防护、循环条件及重复元素定位等关键细节。

二分查找适用于已排序的数组,时间复杂度为 O(log n),比线性遍历快得多。核心思路是每次比较中间元素,根据大小关系缩小一半搜索范围。
基本实现(手写循环版本)
手动实现更清晰,也便于理解边界控制逻辑:
- 定义左右边界 left = 0、right = arr.length - 1
- 循环条件用 left <= right,确保单个元素也能检查
- 计算中点用 mid = left + (right - left) / 2,避免整数溢出
- 若 arr[mid] == target,直接返回 mid;小于则 left = mid + 1;大于则 right = mid - 1
- 循环结束未找到,返回 -1
使用 Arrays.binarySearch()
Java 标准库提供便捷方法,但要注意细节:
- 调用 Arrays.binarySearch(arr, target),要求 arr 必须已升序排列
- 返回值 ≥ 0 表示找到,值即为索引;返回负数表示未找到,其绝对值减 1 是插入位置(保持有序)
- 对基本类型数组(如 int[])直接可用;对象数组需确保元素实现 Comparable 或传入 Comparator
处理重复元素时的定位
标准二分查找只返回“某个”匹配位置。若需最左或最右下标,需微调逻辑:
立即学习“Java免费学习笔记(深入)”;
- 找最左位置:相等时不立即返回,而是 right = mid - 1,最后返回 left
- 找最右位置:相等时 left = mid + 1,最后返回 right
- 注意循环结束后要校验 left/right 是否越界,且对应位置是否真等于 target
常见陷阱与注意事项
实际使用中容易忽略这些关键点:
- 数组必须有序——否则结果不可预测,切勿跳过排序步骤(除非确定已排好)
- 边界计算别写成 (left + right) / 2,大数组可能整型溢出
- 循环条件别写成 left < right,会漏掉单元素情况
- 递归写法虽简洁,但深度大时有栈溢出风险,生产环境推荐迭代版本


















