二分查找以及数组下标的移动规律

二分查找算法

复杂度 log ⁡ 2 N \log_2N log2N
二分查找的前提是待查找的序列必须是有序的。另外一点,C++中的序列都是前闭后开的。如果使用STL,默认是递增顺序,递减的顺序需要自定义比较函数。二分查找可以自己实现或者使用STL的std::binary_search()实现,后者只能给出需要查找的元素是否在某序列中,返回bool值。然而,当我们需要知道元素的具体位置时,需要自己写一个二分查找算法。一下给出了两种方式,注意自定义函数的区间调整。

如果一个容器是有序的,而且元素可以使用==运算符进行比较,那么完全可以使用库函数lower_bound()执行二分查找,函数返回第一个大于等于目标元素的位置,如果所有元素都小于目标元素的迭代器,则返回尾后替代器;同时注意upper_bound()函数,该函数也是执行二分查找,不过是返回第一个大于目标元素的迭代器。利用upper_boundlower_bound之差可以记录相等元素的个数。。

不过,我们要自己掌握这种算法,自己写这种算法时,与STL的区别在于右侧也是闭区间,这样比较好记,而且容易寻找下标的规律。算法终止条件的核心是下界大于上界。下面给出代码:

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

template<typename T>
int BinSearch(vector<T>vec, T key) {
    if(vec.empty()) {
        return -1;
    }
    int low = 0, high = vec.size() - 1;
    while(low <= high) {
        int mid = low + (high - low) / 2;
        if(vec[mid] == key) {
            return mid;
        } else if(vec[mid] > key) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

int main() {
    return 0;
}

二分查找下标的规律总结:

  • 如果可以找到目标,分为两种情况,这两种情况对于子区间同样适用:
    • 区间的两侧是目标: l o w = h i g h = m i d low=high=mid low=high=mid
    • 恰好是 m i d = l o w + ( l o w + h i g h ) / 2 mid=low+(low+high)/2 mid=low+(low+high)/2,此时三者都不变
  • 如果找不到目标,则 l o w = h i g h + 1 low=high+1 low=high+1,此时的 m i d mid mid等于 l o w low low或者 h i g h high high,由具体的运算情景决定
  • 如果 h i g h = l o w + 1 high=low+1 high=low+1时,在这里先不论是否有目标值,此时一定有: m i d = l o w mid=low mid=low。假设我们此时还没找到元素,那么如果目标值小于 m i d mid mid指示值,则 h i g h high high移动向 l o w low low;否则 l o w low low移动向 h i g h high high;最终 m i d = h i g h = l o w mid=high=low mid=high=low
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值