所有函数要求序列已按升序排序(或按自定义比较规则排序)。
头文件:#include <algorithm>
时间复杂度:O(log n)(随机访问迭代器,如vector/array/deque;list不支持)
一、四种核心函数对比
| 函数 | 返回值 | 说明 |
|---|---|---|
lower_bound(beg, end, val) | 第一个 ≥ val 的位置 | 找下界 |
upper_bound(beg, end, val) | 第一个 > val 的位置 | 找上界 |
binary_search(beg, end, val) | bool 是否存在 | 单纯判断 |
equal_range(beg, end, val) | pair<迭代器, 迭代器> | 等于 val 的范围 [lower, upper) |
二、lower_bound — 第一个不小于 val 的位置
auto it = lower_bound(v.begin(), v.end(), val);
// 用法示例
vector<int> v = {1,3,5,7,9};
auto it = lower_bound(v.begin(), v.end(), 5); // 指向 5(索引2)
auto it2 = lower_bound(v.begin(), v.end(), 6); // 指向 7(索引3)
三、upper_bound — 第一个大于 val 的位置
auto it = upper_bound(v.begin(), v.end(), val);
// 示例
auto it = upper_bound(v.begin(), v.end(), 5); // 指向 7(索引3)
auto it2 = upper_bound(v.begin(), v.end(), 7); // 指向 9(索引4)
四、binary_search — 判断是否存在
bool found = binary_search(v.begin(), v.end(), val);
// 示例
if (binary_search(v.begin(), v.end(), 5))
cout << "存在";
五、equal_range — 获取相等元素的区间
auto [l, r] = equal_range(v.begin(), v.end(), val);
// 或 pair<iterator, iterator> p = equal_range(...);
// l = lower_bound, r = upper_bound
六、自定义比较(降序或结构体)
需要保持排序规则与二分规则一致,使用相同的比较函数对象。
// 降序排序的 vector
vector<int> v = {9,7,5,3,1};
// 在降序序列中找第一个 ≤ val 的位置(自定义)
auto it = lower_bound(v.begin(), v.end(), 5, greater<int>());
// 结构体示例
struct Person { string name; int age; };
vector<Person> ps = {{"A",20},{"B",25},{"C",30}};
// 按 age 升序排序后,二分查找 age >= 25
auto cmp = [](const Person& p, int age) { return p.age < age; };
auto it = lower_bound(ps.begin(), ps.end(), 25, cmp);