首先左闭右开的写法,[left,right]
#include <bits/stdc++.h>
#include <vector>
#include <algorithm>
using namespace std;
int search(vector<int>& num ,int target)
{
int left=0;
int right=num.size()-1;
while(left<=right)
{
int middle=(left+right)/2;
if(num[middle]>target)
{
right=middle-1;
}
else if(num[middle]<target)
{
left=middle+1;
}
else
{
return middle;
}
}
return -1;
}
int main()
{
vector<int> num = {90,4,8,6,7};
sort(num.begin(),num.end());
int t=90;
cout<<search(num,t);
return 0;
}
左闭右开的写法 [left,right)
#include <bits/stdc++.h>
#include <vector>
#include <algorithm>
using namespace std;
int search(vector<int>& num,int target)
{
int left=0;
int right=num.size();
while(left<right)
{
int middle=(left+right)/2;
if(num[middle]<target)
{
left=middle+1;
}
else if(num[middle]>target)
{
right=middle;
}
else{
return middle;
}
}
return -1;
}
int main()
{
vector<int> num={78,32,12,34,54};
sort(num.begin(),num.end());
int t=32;
cout<<search(num,t);
}
在代码里做了一些改动,一开始不再是有序数组,因此多了一步sort排序。
对于二分法,第一个就是要注意区间,左闭右闭还是左闭右开。区分好了区间之后就对边界的判断更明确了。有的人总是对middle,middle+1或是middle-1到底该用哪一个感到晕,这里其实有规律。其实无外乎就是在闭合的那一端,middle要么是加一,要么是减一,在非闭合的那一端,不再考虑加或减一,当left==right时返回middle。