二分查找源码解析
Posted javasanity
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找源码解析相关的知识,希望对你有一定的参考价值。
欢迎点击蓝色字关注“javasanity”
之前一篇文章中已经解过一道 leetcode 二分查找的题目了,这篇文章再来分析一下 java 类库中提供的二分查找源码。
对应的类为 java.util.Arrays,方法名为 binarySearch。
-
-
-
-
四个参数(倒数第二个五个参数):从数组指定的范围中查找,中间的两个参数指定范围,该范围为
前闭后开
每种类型数组的两种二分查找方法底层调用的都是同一个叫做 binarySearch0 的私有方法,因此 binarySearch0 也对应提供了不同类型的方法。binarySearch0 支持从数组指定的范围中查找,同样,中间的两个参数用来指定范围,该范围为前闭后开。
这部分主要以 int 类型数组的二分查找源码为例,来看看是怎么写的。
(1)先来看两个参数的 binarySearch 方法。可以看到底层调用 binarySearch0 方法,中间两个参数是 0 和 a.length,即从数组 a 的 [0, a.length) 范围中查找目标值 key。
(2)再来看四个参数的 binarySearch 方法。可以看到底层同样调用 binarySearch0 方法,中间两个参数是 fromIndex 和 toIndex,即从数组 a 的 [fromIndex, toIndex) 范围中查找目标值 key。
但是在调用 binarySearch0 方法之前,会调用 rangeCheck 方法来检查 fromIndex 和 toIndex 的合法性,不合法则抛出异常。
关于这两个参数的合法性,下面截图中方法注释的 @throws 部分写的非常明白(良心博主,翻译都安排的明明白白),不再赘述。
检查 fromIndex 和 toIndex 合法性的代码也非常简单。
(3)最后来看 binarySearch0 方法,会发现,代码几乎和之前 leetcode 二分查找那篇文章中我们写的一样,唯一的区别是:如果没找到目标值 key 时的返回值。
关于这点,上面截图中方法注释的 @return 部分也写的非常明白,不再赘述。
关于没找到目标值 key 时为什么返回的是 -(插入点) - 1 的证明方法,在这里也共享出一个链接以供大家阅读:
https://blog.csdn.net/paralysed/article/details/106583034
其它类型数组的二分查找源码和 int 类型的大同小异,这部分来具体看看。
(1)byte[]、char[]、long[]、short[] 和 int[] 一样,大小比较用的都是大于小于的方式
(2)Object[] 大小比较用的是 Comparable.compareTo 方法
(3)T[] 的大小比较,最后一个参数可以传自定义比较器,如果没传,则默认走的是 Object[] 的二分查找方法
(4)float[] 和 double[] 的大小比较方法和前面类型的都有一点点不一样。不过还好,我们已经了解了 IEEE 754 标准,并且在上一篇一起分析过 Float.java 和 Double.java 的源码,所以,直接上代码(该部分代码对应其 compare 方法源码)
以上是关于二分查找源码解析的主要内容,如果未能解决你的问题,请参考以下文章
一网打尽!二分查找解题模版与题型全面解析
算法和数据结构解析:3 - 二分查找相关问题
算法和数据结构解析:3 - 二分查找相关问题
JAVA源码走读二分查找与Arrays类(未完)
《详解二分查找》视频解说
《漫画算法2》源码整理-1 二分查找树 AVL树 红黑树