说来有点丢人,学算法也快半年了,中午看到一篇二分法的文章,较为详细的给出了二分算法的实现,我下午尝试自己实现的时候,却弄了两个多小时。。
发明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;
}