binarySearch(二分查找法)
JDK API文档:
public static int binarySearch(int[] a,int key)
使用二分搜索法来搜索指定的 int 型数组,以获得指定的值。必须在进行此调用之前对数组进行排序(通过 sort(int[]) 方法)。如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。
参数:
a - 要搜索的数组
key - 要搜索的值
返回:
如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即第一个大于此键的元素索引,如果数组中的所有元素都小于指定的键,则为 a.length。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
binarySearch方法体:
public static int binarySearch(int[] a, int key) {
return binarySearch0(a, 0, a.length, key);
}
解析:
- binarySearch方法需要传递两个参数,一个为查找数组,一个为查找的值
- 方法体中只有一个返回方法,返回方法共四个参数,第一个参数为binarySearch传递过来的数组,第二个参数为0,第三个参数为数组长度,最后一个参数为查找的值,既然要知道如何实现查找那么就继续深入binarySearch0方法
返回方法(binarySearch0):
binarySearch方法体中的返回方法:
/** 参数: a:查找数组 fromIndex:0 toIndex:查找数组长度 key:查找值*/
//★:假设数组长度为10 数值为:1,2,3,4,5,6,7,8,9,10
private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {
int low = fromIndex; //定义变量low,初始值为:0(查找范围初始下标)
int high = toIndex - 1;//定义变量high,初始值为:数组的最后一个值的下标(10-1=9)|(查找范围末尾下标)
while (low <= high) {//判断boolean:low<=数组最后一位下标
int mid = (low + high) >>> 1;//位运算求mid值((0 + 9) >>> 1) = 4
int midVal = a[mid];//定义数组index下标为4的数值(5)|将数组中间下标(mid)的值定义给midVal变量
if (midVal < key)//判断中间值5是否小于要查找的数值
low = mid + 1;//如果中间值小于要查找的数值,那么就将iow变量重新定义为中间值+1
else if (midVal > key)//判断中间值5是否大于要查找的数值
high = mid - 1;//如果中间值大于要查找的数值,那么就将high变量重新定义为中间值-1
else// 如果都不满足就返回中间值的下标|这代表:(中间值(midVal)==查找值(key))
return mid;
}
return -(low + 1); // 虽然上述while代码块常理来说可以查找到中间值并返回,但总有列外,如果while循环体查找不到那么返回-(low(查找范围初始下标)+)1
}
问题:
int mid = (low + high) >>> 1;
提问:这里为什么要使用位运算符,这里借助(low + high) / 2 不是相同的意思吗?
解答:如果我们使用/2那么程序还需要间接进行处理,会减慢程序的运行速度,而我们使用>>>来运算是直接和计算机打交 道,可以提升程序的效率和准确性
binarySearch解析:
-
binarySearch(二分查找法),首先调用此方法需要借助到两个参数,这两个参数的作用在于传递要查找的数组和查找值
-
public static int binarySearch(int[] a, int key) /** *binarySearch(二分查找法),首先调用此方法需要借助到两个参数,这两个参数的作用在于传递要查找的数组(a) *和要查找的值(key) */
-
方法体中只有一个返回值,返回的值为binarySerch0的方法返回值,而binarySerch0方法就是计算key值下标的方法
-
设计的精妙之处就在于在二分查找法,将数组拆分成两个区域查找(大值区域,小值区域),再从两个区域中精准查找是在大区域还是小区域,如果依旧查找不到将继续用分大小区来查找(以此类推),数据庞大的情况下可以比通常使用一个个对应查找要迅速数倍