Appearance
二分查找(Binary Search)
二分查找每次取区间中点元素与目标进行比较,无论结果如何,都能将搜索区间缩小一半,从而在 O(log n) 时间内完成查找。 前提:数组必须有序且支持随机访问(顺序存储结构)。
查找过程
每次取区间 [lo, hi] 的中点 mid = (lo + hi) / 2 进行比较:
- 若
A[mid] = target,查找成功; - 若
A[mid] < target,在右半区间继续(lo = mid + 1); - 若
A[mid] > target,在左半区间继续(hi = mid - 1); - 区间为空(
lo > hi)则查找失败。
过程模拟
以有序数组 [1, 3, 5, 7, 9, 11, 13]、目标 target = 11 为例:
左右边界与插入点
当数组中存在重复元素,或需要确定插入位置时,需要使用二分的边界变体:
- 左边界查找:找到 target 后不立即返回,令
hi = mid - 1继续向左收缩,直至区间为空;最终lo即为首次出现位置。 - 右边界查找:找到 target 后令
lo = mid + 1继续向右收缩;最终hi即为末次出现位置。 - 插入位置:当 target 不存在时,
lo即为维持有序的应插入位置。
算法特性
- 时间复杂度:O(log n)。每次比较缩小一半,最多比较 ⌈log₂(n+1)⌉ 次。
- 空间复杂度:O(1)。迭代实现只需常数额外空间;递归实现为 O(log n) 栈空间。
- 前提条件:数组必须有序且支持 O(1) 随机访问(不适用链表)。
- 稳定查找:通过边界变体可精确定位重复元素的首次或末次出现位置。
Baseline 任务:二分查找
任务内容
完成 ordered_search.cpp,实现以下函数:
- 基础二分查找
int BinarySearch(vector<int>& nums, int target)- 在有序表中查找目标关键字,返回下标或 -1
- 左边界查找
int BinarySearchLeftBound(vector<int>& nums, int target)- 返回 target 首次出现的下标
- 右边界查找
int BinarySearchRightBound(vector<int>& nums, int target)- 返回 target 末次出现的下标
- 插入位置查找
int BinarySearchInsertionPoint(vector<int>& nums, int target)- 返回 target 应插入的位置,使数组保持有序
文件结构
ordered_search.h:函数声明ordered_search.cpp:查找算法核心实现test.cpp:测试程序
验证方式
- 编译:
g++ -std=c++17 test.cpp ordered_search.cpp -o testOrderedSearch - 运行:
./testOrderedSearch