图解二分查找的递归和非递归实现
二、二分查找的递归实现
-
找到数组的中间位置下标mid:int mid = end+((begin-end)/2) -
比较数组中间值和target的大小: -
如果中间值大于target,说明待查找值在mid左边,在左边递归查找; -
如果中间值小于target,说明待查找值在mid右边,在右边递归查找; -
如果中间值等于target,说明找到了待查找值,直接返回 -
如果begin>end,结束递归,说明没有待查找的值
代码实现:
public static int binarySearch(int[] arr, int begin, int end, int target) {
if (begin > end) {
return -1;//返回-1表示没有找到
}
int mid = end + ((begin - end) / 2);
if (target < arr[mid]) {//中间值大于查找值,递归向左边查找
return binarySearch(arr, begin, mid - 1, target);
} else if (target > arr[mid]) {//中间值小于查找值,递归向右边查找
return binarySearch(arr, mid + 1, end, target);
} else {
return mid;//返回target在数组中的位置下标
}
}
注意:
递归结束的条件:begin>end
中间下标的计算公式:由于int mid = (begin + end) / 2 这个计算公式中(begin + end)存在溢出的风险,所以采用int mid = end + ((begin - end) / 2),或者int mid = (begin + end)>>>1
begin和end的更新:low=mid+1,high=mid-1。注意这里的 +1 和 -1,如果直接写成 low=mid 或者 high=mid,就可能会发生死循环。比如,当 high=3,low=3 时,如果 a[3]不等于 value,就会导致一直循环不退出。
启动一个while循环,只要满足begin<=end,就继续执行
找到数组的中间位置下标mid:int mid = end+((begin-end)/2)
比较数组中间值和target的大小:
如果中间值大于target,说明待查找值在mid左边,将end改为mid-1;
如果中间值小于target,说明待查找值在mid右边,将begin改为mid+1;
如果中间值等于target,说明找到了待查找值,直接返回
如果begin>end,结束循环,说明没有待查找的值
图解:
public static int binarySearch(int[] arr,int begin,int end,int target){
while (begin<=end){
int mid = (begin + end) / 2;
if (arr[mid]==target){
return mid;//返回target在数组中的位置下标
}
//如果数组中间值比目标值大,说明在左边,那么把end修改为mid-1,然后在左边继续二分查找
if (arr[mid]>target){
end=mid-1;
}else{
begin=mid+1;
}
}
return -1;
}
注意:
循环的执行条件:begin<=end