小白学算法:透过jdk源码学习二分算法

引论

Java的util包下,有一个Arrays工具类。其中的binarySearch方法是Java大神写好的二分查找法,小白就直接拿这个来研究二分算法了。
话不多说,上源码:

private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = a[mid];

        if (midVal < key)	//判断A
            low = mid + 1;
        else if (midVal > key)	//判断B
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}

注意:这个方法的前提是,传入的数组是一个升序的数组。
下面是jdk中关于此方法的一些描述:

参数:
a - 要搜索的数组
key - 要搜索的值
返回:
如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。

分析

我们着重来分析这个方法的返回值:
为什么找到的时候返回的是对应索引,找不到的时候返回的是 -(插入点)-1
第一:我们先以数学思维考虑二分法
在这里插入图片描述
假如你和你同学在做猜数游戏,按照二分法的思想,在1~100以内猜数。
第一次猜的时候:我们是在1~100这个区间去猜,在这里,low=0high=100mid=50按照二分法的思想,我们首先要问:是比50大还是比50小?

那么可以想见的是,我们最终猜的值肯定是一个数(这话好像有点脑残);但是,你要注意到这意味着什么:这表明**while循环执行到最后一次,一定有low=high=mid**,理解这一点很重要。
第二:在理解了第一步数学思维的基础上,我们就可以来分析这个方法的返回值了。
根据第一步的分析,给定的值key最后肯定是和中间索引对应的值midVal进行比较的,有三种情况:

1.key=midVal

此时,判断A和判断B均不成立,返回mid(即key在数组中的索引)

2.key > midVal

此时判断A成立,low = mid +1。注意:因为 key > midVal,所以如果要将key按照数组的顺序插入数组的话,那插入点不就是low的后一位吗?即 mid+1,所以,此时的low对应的恰好就是key在数组中的插入点。又因为此时(前面提到过当key和midVal比较时,low=high,但此时low加了1)low>high,所以while循环不再执行,开始执行语句:

return -(low + 1); // key not found.

得到的结果正是:(-(插入点) - 1)

3.key < midVal

参照第二种情况,不再赘述。

小白出品,欢迎各位大佬不吝赐教

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值