0

0

C++怎么实现二分查找 C++标准库binary_search【精析】

穿越時空

穿越時空

发布时间:2026-03-09 14:43:18

|

239人浏览过

|

来源于php中文网

原创

binary_search返回bool因其仅判断存在性而不提供位置信息;需下标时应使用std::lower_bound并检查是否等于end()。

c++怎么实现二分查找 c++标准库binary_search【精析】

binary_search 为什么返回 bool 而不是下标

因为它的设计目标只有一个:查“有没有”。它不关心在哪,只回答“存在吗”。这和 std::lower_boundstd::upper_bound 的定位完全不同——后两者才负责定位。

常见错误现象:binary_search 返回 true,但你接着去访问 v[0] 或硬算下标,结果越界或逻辑错乱。它根本不提供位置信息。

  • 如果你需要下标,直接用 std::lower_bound,然后检查是否等于 end()
  • 如果容器是 std::vector 且已排序,binary_search(v.begin(), v.end(), x) 是安全的;但若未排序,结果未定义(不是报错,而是可能返回任意 bool)
  • 注意:迭代器范围必须满足严格弱序,比如自定义比较函数时,comp(a, a) 必须为 false,否则行为未定义

传入自定义比较函数时最容易漏掉的条件

binary_search 查结构体或自定义类型时,很多人只写 comp(a, b),却忘了它必须和排序时用的是**同一个函数对象**。

错误示例:用 std::sort(v.begin(), v.end(), [](auto& x, auto& y) { return x.id 排序,但调用 <code>binary_search 时漏传比较函数,或传了另一个逻辑(比如按 name 比),结果永远返回 false —— 因为底层二分依赖的序关系和实际数据排列不一致。

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

Stable Diffusion Online
Stable Diffusion Online

基于Stable Diffusion搭建的AI绘图工具

下载
  • 务必配对使用:排序用什么比较器,查找也得传什么比较器
  • lambda 捕获变量需注意生命周期:如果比较函数捕获了局部变量,而容器生命周期更长,运行时可能读到野值
  • 函数对象类型要一致:不能一个用 std::less,另一个用手写 lambda,即使逻辑相同,类型不同也会导致模板实例化失败

在 std::set / std::map 上调用 binary_search 是多此一举

std::setstd::map 底层是红黑树,自带 find() 成员函数,平均 O(log n),且返回迭代器,既能判断存在性又能取值。此时用全局 binary_search 不仅冗余,还容易出错。

典型误用:binary_search(s.begin(), s.end(), x) —— 看似可行,但 std::set::iterator 是 const 迭代器,某些标准库实现会因类型推导问题编译失败;更重要的是,它绕过了容器自己的优化路径。

  • std::set,直接用 s.find(x) != s.end()
  • std::map,用 m.find(key) != m.end() 或更简洁的 m.count(key)(注意 count 对 map 永远是 0 或 1)
  • 只有面对原始数组、std::vectorstd::array 这类“无查找能力”的序列时,binary_search 才是合理选择

性能陷阱:迭代器类型影响是否真走二分

binary_search 要求随机访问迭代器(RandomAccessIterator)才能达到 O(log n)。如果误传了 std::list::iteratorstd::forward_list::iterator,代码仍可能编译通过(取决于标准库实现),但内部会退化成线性遍历 —— 完全失去二分意义。

错误信号:明明数据量上万,查找却慢得反常,且 CPU 占用集中在循环判断上。这不是算法问题,是迭代器类型没达标。

  • 安全组合:只对 std::vectorstd::dequestd::array、原生指针(如 &arr[0])使用 binary_search
  • 不确定时,用 std::is_same_v<typename it::iterator_category std::random_access_iterator_tag></typename> 静态断言(C++20 可用 std::random_access_iterator 概念)
  • 别试图对 std::vector<t>::const_iterator</t> 做手脚来“适配”非随机访问容器——没用,类型不匹配就是不匹配

最常被忽略的一点:binary_search 不检查输入范围是否真有序。它假设你已经排好序,连 warning 都不会给。一旦数据没排,返回值就纯粹是垃圾,而且你还很难复现——有时候碰巧 true,有时候 false,调试起来像玄学。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
Sass和less的区别
Sass和less的区别

Sass和less的区别有语法差异、变量和混合器的定义方式、导入方式、运算符的支持、扩展性等。本专题为大家提供Sass和less相关的文章、下载、课程内容,供大家免费下载体验。

216

2023.10.12

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.11.20

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

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

409

2023.09.04

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

561

2023.09.20

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

59

2026.03.06

热门下载

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

精品课程

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

共94课时 | 10.9万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.1万人学习

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

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