二分查找细节永不忘

二分查找中大于小于,甚至判断条件中的 < <= 很容易弄混。下面一起来捋清楚,保证了解原理,不会再错。重点的概念在于选区的区间!
我建议选取的区间为左闭右闭,即[l,r]。当然其他方式也可以,我们不做讲述。
因此需要注意以下三点即可:
1.r = arr.length()-1 而不是length(),这样使得r为末数的下标,有意义。
2. 判断终止条件为l < = r,因为 l,r 都是寻找目标,当其相等时,代表还有一个待验证目标。
3. 每次缩小范围时,l = mid-1, r = mid + 1。原因很简单,我们已经判断过mid 并不是我们的target,因此下次判断的区间并不需要包含mid!


package com.mySearch;

public class binSearch {

//    递归方法,被调用方
    public static int bsearch(int[] arr, int l, int r, int target) {
        if (l <= r) {
            int mid = l + (r - l) / 2;
            if (arr[mid] == target) {
                return mid;
            } else if (target < arr[mid] ) {
                // 由于区间要的是左闭右闭区间,且arr[mid]不是答案,因此,mid-1
                return bsearch(arr, l, mid - 1, target);
            } else if (target > arr[mid]) {
                // 同上,mid+1
                return bsearch(arr, mid + 1, r, target);
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    //    递归方法入口,调用方
    public static int search(int[] arr, int target) {
//        当我们确定 r为len-1时,代表我们整个区间要的是[l,r]
        int l = 0, r = arr.length - 1;
        return bsearch(arr, l, r, target);
    }

//    非递归方法
    public static int searchwithwhile(int[] arr, int target) {
    // 细节与递归相同
        int l = 0, r = arr.length - 1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (target == arr[mid]) {
                return mid;
            } else if (target < arr[mid]) {
                r = mid - 1;
            } else if (target > arr[mid]) {
                l = mid + 1;
            } else {
                return -1;
            }
        }
        return -1;
    }


    public static void main(String[] args) {
        int target = 1;
        System.out.println(search(new int[]{1, 2, 3, 5, 6, 7}, target));
        System.out.println(searchwithwhile(new int[]{1, 2, 3, 5, 6, 7}, target));

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值