参考了一下这个大佬的博客,很厉害
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;
}