二分查很多人是一看就会,一写就费,究其原因是因为不知道什么时候该取“等”,这里我把什么时候该怎么做都写在注释里了。
#include<bits/stdc++.h>
using namespace std;
int arr[10] = {
0,1,2,3,4,5,6,7,8,9};
int test01(int target)
{
//第一种写法:区间左闭右闭[left,right]
//一定要结合区间的概念去理解取值范围
//因为区间是右闭的,所以right能取到,因此因该为数组长度减一
int left = 0,right = sizeof(arr)/4 - 1, mid;
mid = (left + right)/2;
//想要查找的数字
while(left <= right)//这里注意,有没有等于号取决于区间,[1,1],如果区间长度是1的话left就必须等于right,不然区间不存在
{
if(arr[mid] > target){
//这里为什么取right = mid - 1呢? 还是要看区间
//因为arr[mid]已经大于我们要找的数字了,所以arr[mid]这个数不应该去现在我们下一次的循环中
right = mid - 1;
}else if(arr[mid] < target){
//这里取mid + 1 和上面同理
left = mid + 1;
}else{
return mid;
}
//让mid重新取到left和right的区间内
//这一步不写会死循环
mid = (left + right)/2;
}
return -1;
}
int test02(int target)
{
//第二种写法:区间左闭右开[left,right)
//一定要结合区间的概念去理解取值范围
//因为区间是右开的,所以right取不到,因此right应该为数组长度
int left = 0,right = sizeof(arr)/4, mid;
mid = (left + right)/2;
//想要查找的数字
while(left < right)//这里注意,有没有等于号取决于区间,[1,1),如果区间长度是1的话left就必须等于right,不然区间不存在
{
if(arr[mid] > target){
//这里为什么取right = mid呢? 还是要看区间
//因为arr[mid]已经大于我们要找的数字了,所以arr[mid]这个数不应该去现在我们下一次的循环中
//又因为我们的区间右边是开的,如果我们还取mid-1的话,那么我们就会少算一些数进而影响最终答案
right = mid;
}else if(arr[mid] < target){
//这里取mid + 1 和上面同理
left = mid + 1;
}else{
return mid;
}
//让mid重新取到left和right的区间内
//这一步不写会死循环
mid = (left + right)/2;
}
return -1;
}
int main()
{
//区间左闭右闭
cout<<test01(6)<<endl;
//区间左闭右开
cout<<test02(8)<<endl;
return 0;
}