0

0

C++中std::lower_bound和std::upper_bound返回值的含义? (二分查找细节)

冰火之心

冰火之心

发布时间:2026-02-15 16:01:05

|

271人浏览过

|

来源于php中文网

原创

std::lower_bound返回第一个≥target的迭代器,不保证相等;std::upper_bound返回第一个>target的迭代器;二者配合可得等于target的区间,要求容器有序且比较逻辑一致。

c++中std::lower_bound和std::upper_bound返回值的含义? (二分查找细节)

std::lower_bound 返回的是第一个 ≥ target 的迭代器

它不保证元素等于 target,只保证“不小于”。如果所有元素都小于 target,返回 end();如果 target 存在,它指向最左边那个等于 target 的位置;如果不存在,指向第一个比 target 大的位置。

常见错误是以为它“找相等”,结果在 if (*it == target) 前没检查 it != container.end(),导致解引用 end() 迭代器——UB(未定义行为)。

  • 使用场景:去重插入、查找左边界、计算某个值的出现起始位置
  • 容器必须有序(升序),且比较逻辑和排序一致(比如用 greater<int></int> 排序,就得传对应 comp
  • 时间复杂度是 O(log n),但底层依赖随机访问迭代器;对 std::list 用它,性能退化成 O(n)(因为 std::advance 慢)

std::upper_bound 返回的是第一个 > target 的迭代器

它跳过所有等于 target 的元素,直接指向“严格大于”的第一个位置。和 lower_bound 配合,[lower_bound, upper_bound) 就是所有等于 target 的连续区间(如果存在)。

容易踩的坑是误以为 upper_bound - lower_bound 总能算出频次——这仅对支持随机访问的容器(如 std::vectorstd::array)成立;对 std::set,得用 std::distance,而且是线性时间。

立即学习C++免费学习笔记(深入)”;

AISEO
AISEO

AI创作对SEO友好的文案和文章

下载
  • 参数 comp 必须和容器排序所用的一致,否则行为未定义
  • 如果 target 大于等于所有元素,同样返回 end()
  • std::set / std::map,这两个函数内部走红黑树路径,仍是 O(log n),无需担心

为什么两个函数都返回迭代器而不是 bool 或索引?

因为 C++ 算法设计哲学是“操作迭代器”,不是“操作数据”。返回迭代器让你能无缝衔接插入、擦除、构造子范围等操作,比如:vec.insert(lower_bound(vec.begin(), vec.end(), x), x) 直接保持有序。

用索引反而多此一举:需要额外存 begin(),还要处理不同容器的索引类型(size_t vs ptrdiff_t),且不通用。

  • 不要自己写 it - vec.begin() 转索引,除非真需要下标运算
  • 不要对 std::forward_list 用这两个函数——它不支持双向遍历,根本没法二分
  • 自定义类型必须提供可比较的 operator 或传入合法 <code>comp,否则编译失败,错误信息通常很长,关键看有没有 invalid operands to binary expression

一个典型误用:在无序容器上调用

比如对刚 push_back 完的 std::vector 直接调 lower_bound,结果不可预测——算法不检查是否有序,它只是按升序语义一路折半,最终可能返回任意位置。

调试时现象往往是:偶尔对得上,换数据就错;或者返回 end() 即使 target 明明存在。

  • 确保调用前已调用 std::sort(或初始化时就有序)
  • 如果频繁插入又查询,考虑换 std::set,它自动维持有序,find 也是 O(log n)
  • assert(std::is_sorted(v.begin(), v.end())) 在 debug 版本里兜底(注意:C++20 才有 std::is_sorted,旧标准需手写或用 <algorithm></algorithm> 里的等价写法)

实际写的时候,最容易被忽略的是:两个函数对“相等”的定义完全依赖你传的比较逻辑,而不是 == 操作符。哪怕 a == b 为真,只要 comp(a, b)comp(b, a) 都为假,它们就被视为“等价”,lower_bound 就可能停在其中任意一个上。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

810

2023.08.22

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

66

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

46

2025.11.27

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

450

2023.08.14

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

139

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.5万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号