在解决有关二分查找的问题中,边界的判定极其重要。如果判定不当,会导致死循环的发生。

二分查找的模板有两种情况:while(left<right)和while(left<=right),而不同的判定条件会导致后续更新边界值的不同:

以第一种情况为例,首先看到left<right,我们应该去更新left的值,使之有超越right的可能,从而跳出循环,如果只是将left更新为mid,则可能发生left始终等于right的情况,从而死循环,由此,代码实现如下:

//二分查找模板(边界问题的处理)

//为了保证能够跳出while循环,必须对left的值进行更新,而不能将其一直改变为mid
//因为这样,有可能会导致left一直等于mid,从而导致死循环

#include<iostream>
#include<vector>
using namespace std;
int My_Search(vector<int>& nums, int n, int target) {
	int left = 0;
	int right = n - 1;
	int mid = 0;
	while (left < right) {
		mid = (left + right) >> 1;
		if (nums[mid] >= target) {
			right = mid;
		}
		else {
			left = mid + 1;
		}
	}
	return nums[mid] == target ? mid : -1;
}
int main(void) {
	vector<int> nums{ -1,0,3,5,9,12 };
	cout << My_Search(nums, 5, 5) << endl;
    return 0;
}
//或者可以更换while判断的条件,使之为left==right
//这样可以对left和right进行mid+1和mid-1的操作而不会导致死循环

这里的mid=left+right>>1解释如下:

由于位运算符的优先级很低,排在加法运算符之后,所以该式先执行left+right,而右移运算符相当于除以2,故该式可改变为(left+right)/2.