二分查找有两组写法(这里我就写一组了),每组有2个算法,最后所求的意义也不同
找出第一个>=x的第一个位置
#include<iostream>
using namespace std;
const int N=10010;
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int l=1,r=n;
int x;
cin>>x;
while(l<=r)
{
int mid=l+r>>1;
if(a[mid]>=x)r=mid-1;
else l=mid+1;
}
cout<<r+1<<endl;
return 0;
}
在这里,最后一行也可以输出l,从while循环中看条件,如果a[mid]>=x,那么区间一直在左移,也就是说在最后一次判断的时候,r在x的左边位置,而l满足的条件是<x,也就是说l的最终的位置是是停在了x的左边(这个x不仅仅是数组中存在的,也可以是不存在的)
找出<=x的最后一个位置
#include<iostream>
using namespace std;
const int N=110010;
int a[N],n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int l=1,r=n;
while(l<=r)
{
int mid=l+r>>1;
if(a[mid]<=x)l=mid+1;
else r=mid-1;
}
cout<<l-1;
return 0;
}
这里也是同样的道理,最后可以输出l-1,也可以输出r
总结 之所以这样写是因为要避免死循环,因此,我们就仅仅只是改变了原本的mid直接赋值给的区间端点,所以就是直接把原本要输出的东西还原为mid的值就好了