【数组】二分查找的两种实现方式

261 阅读1分钟

二分查找的前提是数组为有序数组

二分查找是一种效率极高的算法,时间复杂度在O(logn)量级。其应用非常广,例如快速定位IP属地,MySQL InnoDB 引擎的底层实现等。

第一种

我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)

区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
/**
 * 创建时间: 2022/9/13 
 * 函数名称: binarySearch
 * 函数功能: 二分查找
 * 函数参数: 
 *  @param arr: 数组 
 *  @param target: 查找的目标值
 *  @return: int: 返回目标值在数组中的位置(-1表示没有查找到)
 *  @author: Snow
 *******************************************************
 */
int binarySearch(int[] arr, int target){
    if(target > arr[arr.length - 1] || target < arr[0]){
        return -1;
    }
    int mid;
    int left = 0;
    int right = arr.length - 1;
    while (left <= right){
        mid = left + (right - left) / 2;
        if(target > arr[mid]){
            left = mid + 1;
        }else if(target < arr[mid]){
            right = mid - 1;
        }else {
            return mid;
        }
    }
    return -1;
}

第二种

第一种方法会了,第二种就很容易出来了。递归其实就是第一种的变种。

/**
 * 创建时间: 2022/9/13
 * 函数名称: binarySearchRecursion
 * 函数功能: 二分查找(递归方式)
 * 函数参数:
 *  @param arr: 数组 
 *  @param target: 查找的目标值
 *  @return: int: 返回目标值在数组中的位置(-1表示没有查找到)
 *  @author: Snow
 *******************************************************
 */
int binarySearchRecursion(int[] arr, int left, int right, int target){
    if(target > arr[right] || target < arr[left]){
        return -1;
    }
    int mid = left + (right - left) / 2;
    if(target > arr[mid]){
        return binarySearchRecursion(arr, mid + 1, right, target);
    }else if(target < arr[mid]){
        return binarySearchRecursion(arr, left, mid - 1, target);
    }else {
        return mid;
    }
}

~~END~~