二分法

参考了一下这个大佬的博客,很厉害

https://blog.csdn.net/zxzxzx0119/article/details/82670761

 

然后下面就是自己总结的二分法代码模板了

#include<bits/stdc++.h>

using namespace std;

//一.通用的二分法模板,两端的范围是整形
//1.最普通的二分写法,范围[L,R]

int bs1(int arr[],int length,int key)
{
    int L=0,R=length-1; //在[L,R]范围内寻找key
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;  //这里之所以不用(L+R)/2是为了防止L+R超出类型范围
        if(arr[mid]==key)
            return mid;
        if(arr[mid]>key)
            R=mid-1;    //key在[L,mid-1]内
        else
            L=mid+1;
    }
    return -1;
}

//2.普通二分查找的另一种写法,区间[L,R)
int bs2(int arr[],int length,int key)
{
    int L=0,R=length;   //注意这里R=length,所以在[L,R)区间内
    int mid;
    while(L<R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]==key)
            return mid;
        if(arr[mid]>key)
            R=mid;      //在[L,mid)中找
        else
            L=mid+1;
    }
    return -1;
}

//3.第一个=key的
int bs3(int arr[],int length,int key)
{
    int L=0,R=length-1; //在[L,R]内查找第一个==key
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]>=key)
            R=mid-1;
        else
            L=mid+1;
    }
    if(L<length&&arr[L]==key)
        return L;
    return -1;
}

//4.第一个>=key
int bs4(int arr[],int length,int key)
{
    int L=0,R=length-1;     //在[L,R]内查找
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]>=key)
            R=mid-1;
        else
            L=mid+1;
    }
    return L;
}

//5.第一个>key
int bs5(int arr[],int length,int key)
{
    int L=0,R=length-1;     //在[L,R]内查找
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]>key)
            R=mid-1;
        else
            L=mid+1;
    }
    return L;
}

//6.最后一个==key的
int bs6(int arr[],int length,int key)
{
    int L=0,R=length-1;     //在[L,R]内查找
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]<=key)
            L=mid+1;
        else
            R=mid-1;
    }
    if(R>=0&&arr[R]==key)
        return R;
    return -1;
}

//7.最后一个<=key的
int bs7(int arr[],int length,int key)
{
    int L=0,R=length-1;
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]<=key)
            L=mid+1;
        else
            R=mid-1;
    }
    return R;
}

//8.最后一个<key的
int bs8(int arr[],int length,int key)
{
    int L=0,R=length-1;
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        if(arr[mid]<key)
            L=mid+1;
        else
            R=mid-1;
    }
    return R;
}

//二.关于判断条件的时候,可能并不是一个语句能解决的
//这个时候可以利用函数进行封装求值,
//可以顺便利用函数直接判断也可以,单独分开来进行判断,如下:
int judge1(int n,int arr[])
{
    return arr[n];
}
int bs81(int arr[],int length,int key)
{
    int L=0,R=length-1;
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        int m=judge1(mid,arr);
        if(m<key)
            L=mid+1;
        else
            R=mid-1;
    }
    return R;
}

int judge2(int n,int arr[],int key)
{
    if(arr[n]<key)
        return 1;
    return 0;
}
int bs82(int arr[],int length,int key)
{
    int L=0,R=length-1;
    int mid;
    while(L<=R)
    {
        mid=L+(R-L)/2;
        int m=judge2(mid,arr,key);
        if(m)
            L=mid+1;
        else
            R=mid-1;
    }
    return R;
}

//三.数组两端的类型为浮点型

//1. 关于数据类型是浮点数的二分法,模板大概就是这样子了,可能会有小差池吧
double  bs9(double a,double b,double key)
{
    double eps=1e-10;
    double L=a,R=b; //在[L,R]范围内寻找key
    double mid;
    while(L+eps<=R)
    {
        mid=L+(R-L)/2;  //这里之所以不用(L+R)/2是为了防止L+R超出类型范围
        if(mid<=key)
            L=mid;    //key在[L,mid-1]内
        else
            R=mid;
    }
    return R;      //这里好像返回L或者R都行吧
}

int main()
{

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值