处理边界索引指向:保证循环不变量,虽然left和right的值在不断变化,但待查找的target在[l…r]的范围里的声明是不变的,控制边界保证循环不变量
public int binarySearch(E arr[], E target, int n) {
int left=0;
int right=n-1;//在[left..right]的范围里寻找target
while(left<=right) {//没有可查找内容时跳出循环;当left==right时,区间[left...right]仍然有可查找的元素,
// 要继续查找下去,所以循环条件设置成left<=right
int mid = left+(right-left)/2;
if(arr[mid].compareTo(target)==0)
return mid;
else if (arr[mid].compareTo(target) < 0)//更新左边界
left= mid + 1;//根据left的定义确定更新值,target在[left..right]的范围里
//arr[mid]不是要寻找的target,target在[mid+1...r]中
//不需要在待查找范围中包含肯定不是target的索引
else right = mid - 1;//target<arr[mid]
//target在[l...mid-1]中
}
//没有任何区间含有要查找的target
return -1;
}
public int binarySearch2(E arr[], E target, int n) {
int left=0;
int right=n;//在[left..right)的范围里寻找target
while(left<right) {//没有可查找内容时跳出循环;当left==right时,区间[left...right)依然是无效的,如[42,42),[42,43)有效
// 要继续查找下去,所以循环条件设置成left<=right
int mid = left+(right-left)/2;
if(arr[mid].compareTo(target)==0)
return mid;
else if (arr[mid].compareTo(target) < 0)//更新左边界
left= mid + 1;//根据left的定义确定更新值,target在[left..right)的范围里
//arr[mid]不是要寻找的target,target在[mid+1...r)中
//不需要在待查找范围中包含肯定不是target的索引
else right = mid;//target<arr[mid]
//target在[l...mid-1]中,right是开区间,更新为mid,如果更新为mid-1,漏掉了一个可能是target的arr[mid-1]
//target在[l..mid)中
}
//没有任何区间含有要查找的target
return -1;
}