标签:二分查找
二分查找原理很简单,但是边界条件容易出错,出现死循环等,要想彻底分清楚,应该要理解透彻,大家可以用先思考,然后用例子来验证,下面是我的思路,如果有错误,请指正。我们先看变形一:如果有很多待查找的数字,找出最大的,所以最大的一定是在最右边,为了能够把左右两个数进行对比,循环结束的时候,左右指针对应的数要相隔1,所以循环结束的条件是left < right -1;要想保留最大下标,当data[mid] == value时,不能结束,因为data[mid+1]也可能等于value,所以要继续遍历,这时让left = mid,所以小于和等于要合并。变形二类似。再看变形三:为了找data[i]<value的最大i,当data[i]==value时也不能结束,此时,由于i肯定是在等于value的那个下标的左边,所以当data[i]==value时,要把right = mid继续遍历,即把大于和等于合并,而此时和变形一不同的时,要找的是小于,而不是等于,所以当data[i]>=value时,结果肯定在i的左边,不可能包括i,所以right = mid -1而不是mid,变形四类似。
标准的二分查找一:
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size()-1;//注意1 while(left <= right)//注意2 { int mid = left + ((right - left) >> 1);//注意3 if(data[mid] < value)left = mid + 1; else if(data[mid] > value)right = mid - 1;//注意4 else return mid; } return -1; }
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size();//注意1 while(left < right)//注意2 { int mid = left + ((right - left) >> 1); if(data[mid] < value)left = mid + 1; else if(data[mid] > value)right = mid;//注意3 else return mid; } return -1; }
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size()-1;//注意1 while(left < right - 1) { int mid = left + ((right - left) >> 1); if(data[mid] <= value)left = mid;//注意2 else right = mid;//注意3 } if(data[right] == value)return right; if(data[left] == value)return left; return -1; }
变形二:如果有多个满足条件,返回序号最小的
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size()-1;//注意1 while(left < right - 1) { int mid = left + ((right - left) >> 1); if(data[mid] >= value)right = mid;//注意2 else left = mid;//注意3 } if(data[left] == value)return left; if(data[right] == value)return right; return -1; }
变形三:求最大的i,使得data[i] < value
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size()-1;//注意1 while(left < right - 1) { int mid = left + ((right - left) >> 1); if(data[mid] < value)left = mid;//注意2 else right = mid-1;//注意3 } if(data[right] < value)return right; if(data[left] < value)return left; return -1; }
变形四:求最小的i,使得data[i] > value
int biSearch(vector<int>& data,int value) { int left = 0,right = data.size()-1;//注意1 while(left < right - 1) { int mid = left + ((right - left) >> 1); if(data[mid] > value)right = mid;//注意2 else left = mid + 1;//注意3 } if(data[left] > value)return left; if(data[right] > value)return right; return -1; }
标签:二分查找
原文地址:http://blog.csdn.net/fangjian1204/article/details/38705183