二分查找法也可以使用递归的方式来实现,当数据量小时,可以使用递归来使代码更容易理解。
下面时代码示例和实现思路:
1.测试方法:
@Test
public void test(){
//创建一个测试数组
int[] arr = new int[100000000];
for (int i = 1; i <= 99999999; i++) {
arr[i-1] = i;
}
//查找目标
int target = 59469999;
long Start=System.nanoTime();//开始时间
int index=binarySearch(arr,target);//调用自定义的binarySearch方法获取索引
long End=System.nanoTime();//结束时间
if(index==-1){
System.out.println("未找到,-1");
}else {
System.out.println("找着了,索引为:"+index);//命中则输出索引,程序结束
}
System.out.println("耗时:"+(End-Start)/Math.pow(10,6)+"ms");//耗时
}
2.binarySearch方法:
/**
*公开方法
*/
public static int binarySearch(int[] arr,int target){
return f(arr, target, 0, arr.length - 1);
}
/**
*内部私有方法
*/
private static int f(int[] arr, int target, int left, int right) {
if(left > right){
return -1;
}
int mid=(left + right)>>>1;
if(arr[mid]== target){
return mid;
}else if(arr[mid]> target){
return f(arr, target, left, mid - 1);//中间值大于目标值,排除右半边范围,并重新递归调用
}else{
return f(arr, target, mid + 1, right);//中间值小于目标值,排除左半边范围,并重新递归调用
}
}
这里用一个公开类来调用内部私有类的方式来简化这个整体方法的调用参数,便于调用者使用。
使用改变调用参数的方式来递归调用 f(...) 方法的方式来替代循环方式,这样是不是更容被读懂呢。
但是这种方式在数据量大的时候它的性能时不及循环方式的,它会因多次递归而产生很多额外开销,甚至如果数据量过大的会话还会导致栈溢出,所以只推荐在数据量小的场景下使用。