c++二分查找模板

一、查找已递增排序数组A中 大于等于(或者大于) 给定target的 第一个 元素的下标

//当eq_enable为true时  对应【大于等于】的情况
//当eq_enable为false时 对应【大于】的情况
int binarySearch_GE_or_G(vector<int>& A, int target, bool eq_enable) {
        int left = 0, right = (int)A.size() - 1, ans = (int)A.size();
        while (left <= right) {
            //int mid = (left + right) / 2;
            //上面的这种写法可能会造成int求和溢出,因此统一写成下面的这种形式
            int mid = left + (right-left) / 2;
            
            if (A[mid] > target || (eq_enable && A[mid] == target)) {
                ans = mid; //标出可能成为答案的点
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }

//若ans等于A.size()说明没有找到满足条件的值

二、查找已递增排序数组A中 小于等于(或者小于) 给定target的 最后一个 元素的下标

//当eq_enable为true时  对应【小于等于】的情况
//当eq_enable为false时 对应【小于】的情况
int binarySearch_LE_or_L(vector<int>& A, int target, bool eq_enable) {
        int left = 0, right = (int)A.size() - 1, ans = (int)A.size();
        while (left <= right) {
            //int mid = (left + right) / 2;
            //上面的这种写法可能会造成int求和溢出,因此统一写成下面的这种形式
            int mid = left + (right-left) / 2;
            
            if (A[mid] < target || (eq_enable && A[mid] == target)) {
                ans = mid; //标出可能成为答案的点
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }

同样,若ans等于A.size()说明没有找到满足条件的值。此外,代码2和代码1十分相似,可以对比学习

总结:
第一次看上面的代码可能会觉得比较奇怪,多思考几种不同的情形做遍历就能够熟悉了,核心思想为:
利用位置mid和数组的有序性作排除法,确定下一个可疑区是[left,mid-1] 还是 [mid+1,right],经过不断地重复mid判断和可疑区长度减半,最终就能实现找点的功能了。

扩展
作为练习,感兴趣的读者可以试试实现一下以下两个需求:
三、查找已递减排序数组A中 小于等于(或者小于) 给定target的 第一个 元素的下标
四、查找已递减排序数组A中 大于等于(或者大于) 给定target的 最后一个 元素的下标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值