提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
二分查找(Binary Search)
一、左闭右闭的二分查找
左闭右闭比较常见,直接放代码
int bin_search1(int *nums,int len,int n)//左闭右闭
{
int left = 0;
int right = len-1;
while (left <= right)
{
int mid = left + ((right - left) >> 1);
if (nums[mid] < n)
{
left = mid + 1;
}
else if (nums[mid] > n)
{
right = mid - 1;
}
else
return mid;
}
return -1;
}
注意点:
①left<=right:这里在left与right指向同一位置时,再进去判断一次
②初始化right要指向最后一个元素,这里与左闭右开不同,我们在讲左闭右开时讲他们的区别
③left和right都要变动,分别加一减一,与左闭右开不同,我们也在下面讲
二、左闭右开
注意点
①首先,我们要知道一点,就是(left+right)/2时,它的结果是往左偏的
②left<right是没有等号的,意味着在left与right在指向相邻位置的时候就应当是最后一次循环了,结合①,若查找的值存在,那么它一定是在left指向的位置,一定不能在right的位置,否则最终的mid落在left,等left==right时已经退出循环了。
③对应上面的左闭右闭,right=len,要指向末尾后面一位,也是为了满足②,right一定会在查找值n的后面一位,而left最终指向n,通过①,mid落在left所指位置,至此找到n,退出循环。
如下图:
代码实现:
int bin_search2(int* nums, int len, int n)
{
int left = 0;
int right = len;//保证right不会指向n值
while (left < right)
{
int mid = left + ((right - left) >> 1);
if (nums[mid] < n) left = mid + 1;//left最终会指向n(若存在n值)
else if (nums[mid] > n) right = mid;//right永远不可能指向n
else return mid;
}
return -1;
}
三 、区别
左闭右闭和左闭右开的区别主要在最后退出循环的方式不同,左闭右闭是在left与right指向同一位置后再次进入循环判断,而左闭右开则是在left与right指向相邻位置时就直接决定胜负了(默认left为最终的mid)