原理
二分查找(Binary Searc)算法,也叫折半查找算法。二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。
算法复杂度为O(logn)。
如果查找值比中间位置的元素小,则从数组的左边继续查找,如果查找值比中间位置的元素大,则从数组的右边继续查找。
局限性
-
依赖数组结构
-
针对的是有序数列
代码实现
二分查找可以使用循环或者递归来实现
循环
/**
* 循环版二分查找
*
* @param nums 数组
* @param target 要查找的值
* @return
*/
public int bserach(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
//获取中间坐标
int mid = low + (high - low) / 2;
if (nums[mid] < target) {
//如果中间值小于查找值,则从数组的右边继续查找
low = mid + 1;
} else if (nums[mid] > target) {
//如果中间值大于查找值,则从数组的左边继续查找
high = mid - 1;
} else {
return mid;
}
}
return -1;
}
递归
/**
* 递归算法实现二分查找
*
* @param nums 数组
* @param target 要查找的值
* @param low 左下标
* @param high 右下标
* @return
*/
public int rsearch(int[] nums, int target, int low, int high) {
if (low > high) {
return -1;
}
//计算中间坐标
int mid = low + (high - low) / 2;
if (nums[mid] > target) {
//如果中间值大于查找值,则从数组的左边继续查找
return rsearch(nums, target, low, mid - 1);
} else if (nums[mid] < target) {
//如果中间值小于查找值,则从数组的右边继续查找
return rsearch(nums, target, mid + 1, high);
} else {
return mid;
}
}
注意事项
中间值得计算有两种方式:
方式一:int mid = (low +high)/2
方式二:int mid = low + (high - low)/2
。
扫描二维码关注公众号,回复:
9259395 查看本文章
方式一存在溢出的风险,当low
和high
比较大时,有可能会导致mid
的值错误,从而使程序出错。
方式二则可以保证生成的mid
一定大于low
,小于high
。