二分查找法也叫折半查找法
前提:数组应该是有序的
时间复杂度是 O( logn),(号称 42亿里的数据只需要执行 32次就能找到目标值)
所以有序树的查找也很快(也是类似折半查找法)
![](https://img-blog.csdnimg.cn/img_convert/e57c0a2decae1b9873c5eed9b5932c31.png)
![](https://img-blog.csdnimg.cn/img_convert/d68450b65b19bebea0c1d75441e63294.png)
代码如下:
/**
* 功能描述 : 递归实现 二分查找法
* 重复操作:每次将子区间折半
* 终止条件:待折半区间 长度为1(或者只有一个元素终止递归)
* @author guoyiguang
* @date 2023/1/7
* @param
* @return
*/
public int binarySearch(int[] array ,int start ,int end,int target){
// target = 3
// 1,3,5,7,9
// 递归终止条件 ①
if(start == end ){
// 和目标值 target 比较,一样,则返回下标,否则返回 -1
if(array[start] == target){
return start;
}
return -1;
}
// 递归终止条件 ②
int middle = (start+end)/2;
// 刚好等于目标值
if(array[middle] == target){
return middle;
// 中间值比目标值大,取数组 左边重新折半
}else if(array[middle] > target){
// target = 3 ,start = 0;middle-1 = end = 1
// 错误写法 ①①:
// binarySearch( array , start ,middle-1, target);
// 正确写法 是要加 return 的
return binarySearch( array , start ,middle-1, target);
// 中间值比目标值小,取数组 右边重新折半
}else{
// target = 3 ,start = middle+1 = 1; end = 1
// 错误写法 ①②:
// binarySearch( array , middle+1 ,end, target);
// 正确写法: 需要加个 return
return binarySearch( array , middle+1 ,end, target);
}
// 错误写法:
// 错误原因: 上面①① 和 ①② 是没有 return 关键字的,假如 程序找到了 target 然后 return start,这个
// binarySearch( array , start ,middle-1, target)
// or binarySearch( array , middle+1 ,end, target)
// 只是代表 这两个语句是执行完了,但是 走到最后 还有 下面的语句 return -1 没有走,于是程序就走了
// return -1
// return -1;
}
// 非递归实现:
/**
* 功能描述: 非递归二分查找
* @author guoyiguang
* @date 2023/1/7
* @param
* @return
*/
public int binarySearchNoRecursion(int[] array,int target){
// 1,3 ,5 ,7,9
int low = 0;
int middle = ( array.length-1)/2;
int max = array.length-1;
//有终止条件且不知道循环几次可以考虑 while 循环
while(low <= max){
// 终止条件
if(array[middle] == target){
// 结束 while 循环
return middle;
}else if (array[middle] > target){
// target 在 middle 左边
max = middle-1;
middle = (low+max)/2;
}else{
low = middle+1;
middle = (low+max)/2;
}
}
return -1;
}