二分法详解

说来有点丢人,学算法也快半年了,中午看到一篇二分法的文章,较为详细的给出了二分算法的实现,我下午尝试自己实现的时候,却弄了两个多小时。。
发明KMP算法的Knuth大佬就说过“Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky."二分法的原理人人都懂,可是具体实现起来又要考虑各种细节。包括查找的范围、结束的条件、返回值的确定等等。
下面把下午实现的代码贴上,分为二分搜索单个值,二分搜索左边界和搜索右边界。踩了不少坑,希望下次再写的时候印象可以深刻点。


```#include<iostream>
using namespace std;
int binary_search(int num[],int len,int target);
int lower_bound(int num[],int len,int target);
int upper_bound(int num[],int len,int target);
int main()
{
    int n,m;
    int num[1000];
    while(cin>>n>>m)
    {
        for(int i=0;i<n;++i)
        {
            cin>>num[i];
        }
        cout<<lower_bound(num,n,m)<<endl;
        cout<<upper_bound(num,n,m)<<endl;
    }
    
    return 0;
}
int binary_search(int num[],int len,int target)
{
    int lo=0,hi=len-1;
    int mid;
    while(lo<=hi)
    {
        mid=lo+((hi-lo)>>1);
        if(num[mid]==target){
            return mid;
        }
        else if(num[mid]>target){
            hi=mid-1;
        }
        else if(num[mid]<target){
            lo=mid+1;
        }
    }
    return -1;
}

int lower_bound(int num[],int len,int target)
{
    int lo=0,hi=len-1;
    int mid;
    while(lo<=hi)
    {
        mid=lo+((hi-lo)>>1);
        if(num[mid]==target){
            hi=mid-1;
        }
        else if(num[mid]>target){
            hi=mid-1;
        }
        else if(num[mid]<target){
            lo=mid+1;
        }
    }
    if(num[lo]==target)    return lo;
    return -1;
}
int upper_bound(int num[],int len,int target)
{
    int lo=0,hi=len-1;
    int mid;
    while(lo<=hi)
    {
        mid=lo+((hi-lo)>>1);
       // cout<<mid<<endl;
        if(num[mid]==target){
            lo=mid+1;
        }
        else if(num[mid]>target){
            hi=mid-1;
        }
        else if(num[mid]<target){
            lo=mid+1;
        }
    }
    if(num[lo-1]==target)    return lo-1;
    return -1;
}




    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值