一、核心原理与特性
二分查找是一种**对数时间复杂度(O(log n))**的高效搜索算法46,需满足两个前提条件:
- 数据存储在连续内存空间(如数组)
- 数据按升序/降序有序排列35
算法通过折半比较缩小搜索范围:
- 初始化左右边界
left=0
、right=length-1
- 计算中间位置
mid = left + (right - left)/2
(避免整数溢出) - 比较
arr[mid]
与目标值,调整左右边界18
二、标准实现步骤(C++迭代版)
Cpp
int binarySearch(int arr[], int size, int target) { int left = 0, right = size - 1; while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] == target) return mid; if (arr[mid] < target) left = mid + 1; else right = mid - 1; } return -1; // 未找到 }
关键点:
- 循环终止条件
left <= right
确保完整搜索区间覆盖48 - 边界调整时
mid±1
避免死循环4
三、边界处理进阶
1. 查找第一个/最后一个匹配项
Cpp
// 查找第一个等于target的位置 int findFirst(int arr[], int size, int target) { int left = 0, right = size - 1, res = -1; while (left <= right) { int mid = left + (right - left)/2; if (arr[mid] >= target) { right = mid - 1; if (arr[mid] == target) res = mid; } else { left = mid + 1; } } return res; }
此变体通过记录临时结果处理重复元素26
2. 旋转数组查找
适用于部分有序数组(如[4,5,6,7,0,1,2]):
- 通过比较
arr[mid]
与左右边界判断有序区间 - 调整搜索方向至目标可能存在的区域76
四、应用场景与优化
场景类型 | 适用案例 | 优化策略 |
---|---|---|
精确匹配 | 有序数组元素定位 | 标准二分法 |
范围查找 | 统计成绩分布、查找IP归属地 | 边界变体(lower/upper_bound) |
数学问题转化 | 求平方根、寻找峰值 | 调整比较条件 |
工程实践 | 数据库索引、缓存查找 | 结合跳表等数据结构 |
五、调试工具推荐
- Valgrind:检测内存越界问题1
- 边界测试用例:
- 目标为第一个/最后一个元素
- 数组中全为相同元素
- 空数组或单元素数组
完整代码实现和进阶案例可参考146中的项目实例。当处理动态数据集时,建议结合平衡二叉搜索树(STL中的
set/map
)实现高效插入与查找。