C++ STL <algorithm> 二分查找 lower_bound, upper_bound,equal_range和binary_search底层实现分析

函数功能总结

在复习时学到STL的二分查找算法,基本上是四个:lower_bound,upper_bound,equal_range和binary_search,四个函数的基本功能如下所示:

函数名 功能
lower_bound( begin,end,num) 要求数组从小到大非递减排序,从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num) 要求数组从小到大非递减排序,从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 在 [first, last) 区域内查找第一个大于val的元素,并且比较函数自定义
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 查找[first, last)区域中第一个大于val的元素,并且比较函数自定义
pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val); 找到 [first, last) 范围中所有等于 val 的元素。对于equal_range函数,当查找成功时:第 1 个迭代器指向的是 [first, last) 区域中第一个等于 val 的元素;第 2 个迭代器指向的是 [first, last) 区域中第一个大于 val 的元素。反之如果查找失败,则这 2 个迭代器要么都指向大于 val 的第一个元素(如果有),要么都和 last 迭代器指向相同
pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 根据 comp 指定的规则,找到 [first, last) 范围内所有满足比较函数且等于val 的元素
bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); 查找 [first, last) 区域内是否包含 val
bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp) 根据 comp 指定的规则,查找 [first, last) 区域内是否包含 val

为什么写这篇文章

在学习过程中我想要从底层实现看懂每个查找算法的执行过程,看到equal_range其实是调用lower_bound和upper_bound两个模板函数后,对参考材料 1:C++ lower_bound() upper_bound() 函数用法详解(深入了解,一文学会)文中一句话产生了疑惑:
在这里插入图片描述
所以经过代码一步步测试后明确了底层实现,下面来一步步阐述。

先总结答案

  • 在lower_bound的自定义比较函数中,val作为第一个实参传入;而upper_bound将val作为第一个实参传入。
  • equal_range的底层实现基于lower_bound和upper_bound两个函数,并且upper_bound函数的开始迭代器first 来自 lower_bound返回的迭代器。

lower_bound的底层实现

lower_bound() 函数定义在头文件中,其语法格式有 2 种,分别为:

//在 [first, last) 区域内查找不小于 val 的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val);
//在 [first, last) 区域内查找第一个不符合 comp 规则的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val, Compare comp);

其中,first 和 last 都为正向迭代器,[first, last) 用于指定函数的查找范围;val 用于指定目标元素;comp 用于自定义比较规则,此参数可以接收一个包含 2 个形参(第二个形参值始终为 val)且返回值为 bool 类型的函数,可以是普通函数,也可以是函数对象。
lower_bound的底层实现代码可以在<stl_algo.h>头文件找到
在这里插入图片描述
易理解的底层实现如下所示。
可以看出默认比较方法为迭代器指向对象小于目标元素*it<val时开始位置后移到比较元素下一位,而不满足该条件时结束位置前移到比较元素;而自定义比较函数则是将判断条件改为comp(*it,val)

template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
   
    ForwardIterator it;
    iterator_traits<ForwardIterator>::difference_type count, step;
    count = distance(first,last);
    while (count>0)
    {
   
        it = first; step=count/2; advance (it,step);
        if (*it<val) {
   //对应第 1 种语法格式
            first=++it;
            count-=step+1;
        }
        else count=step;
    }
    return first;
}
template <class ForwardIterator, class T, class Compare>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp)
{
   
    ForwardIterator it;
    iterator_traits<ForwardIterator>::difference_type count, step;
    count = distance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值