STL源码剖析——二分查找

版本一:lower_bound(应用于有序区间)

  • 在已排序的[first,last)中寻找元素value。

    • 区间内有与value值相等的元素,返回一个迭代器,指向其中第一个元素。即有多个相等的值时,返回第一个相等的位置。
    • 区间内没有与value值相等的元素,返回“假设这样的元素存在时应该出现的位置”。即第一个大于value的元素的位置。
  • 图解
    这里写图片描述

版本二:upper_bound(应用于有序区间)

  • 在已排序的[first,last)中寻找元素value。

    • ”在不破坏顺序的情况下,可插入value的最后一个合适的位置“。
    • 如果迭代器存在,那么它返回的迭代器将指向value的下一个位置。
  • 图解
    这里写图片描述

binary_search(应用于有序区间)

  • 在已排序的[first,last)中寻找元素value。

    • 区间内有等同于value的元素,返回true,否则返回false。
  • 结合版本一

  • 结合版本二

  • 版本一与版本二的区别

    • 对于区间内与value相等的元素的区间划分。

程序

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

//仿lower_bound函数
vector<int>::iterator  lowerBound(vector<int>::iterator first, vector<int>::iterator last, const int& val) {
    int len = last - first;  //元素个数
    while (len > 0) {
        int half = len >> 1;
        auto middle = first + half;
        if (*middle < val) {
            first = middle;
            ++first;
            len = len - half - 1;
        }
        else {
            len = half;
        }
    }
    return first;
}

//仿upper_bound函数
vector<int>::iterator  upperBound(vector<int>::iterator first, vector<int>::iterator last, const int& val) {
    int len = last - first;  //元素个数
    while (len > 0) {
        int half = len >> 1;
        auto middle = first + half;
        if (*middle > val) {
            len = half;
        }
        else {
            first = middle;
            ++first;
            len = len - half - 1;
        }
    }
    return first;
}

bool binarySearch(vector<int>::iterator first, vector<int>::iterator last, const int& val) {
    auto res = lowerBound(first, last, val);
    return res != last && *res == val;
}

bool binarySearch2(vector<int>::iterator first, vector<int>::iterator last, const int& val) {
    auto res = upperBound(first, last, val);
    return *(res-1) == val;
}

int main(int argc, char* argv[]) {

    vector<int> vec{ 12,17,23,23,28,31,34,56 };
    auto res = lower_bound(vec.begin(), vec.end(), 23);
    cout << res - vec.begin() << endl;   //2
    cout << *lower_bound(vec.begin(), vec.end(), 23) << endl;  //23
    auto it = lower_bound(vec.begin(), vec.end(), 56);
    it == vec.end() ? cout << "yes" << endl : cout << "no" << endl; //no

    cout << *upper_bound(vec.begin(), vec.end(), 23) << endl;  //28
    it = upper_bound(vec.begin(), vec.end(), 56);
    it == vec.end() ? cout << "yes" << endl : cout << "no" << endl;  //yes


    cout << *lowerBound(vec.begin(), vec.end(), 23) << endl;
    cout << lowerBound(vec.begin(), vec.end(), 23) - vec.begin() << endl;

    cout << *upperBound(vec.begin(), vec.end(), 23) << endl;

    cout << binarySearch(vec.begin(), vec.end(), 23) << endl;
    cout << binarySearch(vec.begin(), vec.end(), 24) << endl;
    cout << binarySearch2(vec.begin(), vec.end(), 56) << endl;
    getchar();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值