二分查找(函数法)

1.二分查找的前提

  • 只有单调的序列才能进行二分查找;

  • 一般为单调不减,单调不增需要像 sort() 一样修改比较函数;

2.binary_search( ) 函数

  • binary_search( ) 是算法库(algorithm)函数里面的,用于在一个已经排好序的序列(数组或者容器)中查找目标值target;

  • 底层实现为进行二分查找,函数返回一个 bool 值来表示目标值 target 是否存在于此序列中

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> a = {1,2,4,7,8,9,12};
    int target = 8;
    bool retult = binary_search(a.begin(),a.end(),target);	//前两个参数为查找范围始终点,第三个参数为target;
    if(retult)	cout << "yes";
    else	cout << "no";
    return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int a[10] = {1,2,4,7,8,9,12};
    int target = 8;
    bool retult = binary_search(a,a+7,target);	//迭代器可以,数组地址也可以
    if(retult)	cout << "yes";
    else	cout << "no";
    return 0;
}

3.lower_bound( ) 和 upper_bound( )函数

1)lower_bound( )

  • 是在非降序序列中寻找 target 值的所在地址;

  • lower_bound(a,b,target)会返回此序列 [a,b) 中第一个大于等于 target 值的地址

  • 想获得其下标需要使用其返回值减去a的地址,即 a.begin() 或者 a ;

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int a[10] = {1,3,2,11,8,9,10};
    int target = 8;
    sort(a,a+7);
    cout << "target第一次出现在:" << lower_bound(a,a+7,target)-a;
    return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> a = {1,3,2,11,8,9,10};
    int target = 8;
    sort(a.begin(),a.end());
    cout << "target第一次出现在:" << lower_bound(a.begin(),a.end(),target)-a.begin();
    return 0;
}

2)upper_bound( )

  • 与 lower_bound( ) 相同,都是在非降序序列;

  • upper_bound(a,b,target) 返回此序列 [a,b) 中第一个大于 target 值的地址

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> a = {1,3,2,11,8,8,8,8,8,9,10};
    int target = 8;
    sort(a.begin(),a.end());
    cout << upper_bound(a.begin(),a.end(),target)-a.begin();
    return 0;
}

3)总结

  • 当一个序列中存在多个 target 值时,lower_bound( ) 所得到的是序列中第一个 target 值所在的下标a,upper_bound( ) 所得到的是序列中第一个大于 target 值所在的下标b,故此此序列下标 [a,b) 的所有数据均为 target ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值