算法—二分查找

必要条件:给定的数组必须有序,否则不适用二分查找。如果传入的数组无序,则要先对其排序,再进行二分,查找。那排序问题可参考其它排序算法。这篇博文的重点是讲二分。

核心思路:二分区间,找到划分的区间中点位置的元素,与输入比较

具体实现步骤:
1)设置查找区间的左端点 l,初始化为原数组的最小的索引。
2)设置查找区间的右端点 r,初始化为原数组的最大索引。
3)只要左端点值小于等于右端点值,从第4步开始进行操作;否则结束循环,查找完毕,返回一个标志如-1,表示在数组中都没找到与value相等的值,不再进行下面的操作。
4)对给定的区间开始二分,得到数组的中点位置元素的索引mid=l+(r-l)/2
5) 将区间中点的元素与查找目标比较。
6)若目标元素与区间中间位置的元素相等,则返回目标元素在原数组中索引,并结束查找,不再进行下面的操作;否则进行下面的步骤。
7)若目标元素小于区间中间位置的元素,说明查找目标可能存在于较小的区间内,所以调整右端点的索引,r=mid-1,使查找范围变为两个查找区间中较小的一个,跳转到第4步执行。
8)若目标元素大于区间中间位置的元素,说明查找目标可能存在于较大的区间内,所以调整左端点的索引l=mid+1,使查找范围变为两个查找区间中较大的一个,跳转到第4步执行。

温馨提示:计算中点mid=l+(r-l)/2与mid=(l+r)/2,人算的话都可以,因为人的大脑存储信息不像电脑那般固定大小,对于固定数据类型存储空间的机器来说,计算l+r是存在bug的。

我们知道,数据类型在计算机里存储都是有长度限定的。
如果l和r都很大,快接近某种类型的最大值了。
那计算机计算l+r,就会得到错误结果,因为计算结果很容易就超过这种类型所能存储的最大容量,因而会把计算结果高位溢出,这样显然的不到正确结果。
而l+(r-l)/2这种方式就不会存在上述问题,因为r和l如果在编译时都不报错,那r-l显然也不会存在问题,把r-l的结果除以2再与l相加,也不会存在问题,所以整个计算过程都不会有问题,这也是二分查找中很关键的一步。

代码实现与详细解读:

package compute;

/**
 * 二分查找
 *@create by gzx on 2022-2-11
 */
public class BinarySearch {
	public static void main(String[] args) {
		int[] src= {1,2,3,5,6,7,7,8,9};
		
		int i = search(src, 10);
		System.out.println(i);
		
		int j = search(src, 0);
		System.out.println(j);
		
		int k = search(src, 7);
		System.out.println(k);
		
		int m = search(src, 4);
		System.out.println(m);
		
		int n = search(src, 6);
		System.out.println(n);
	}
	/**
	 * @param src 原数组,必须为有序数组
	 * @param target 要在数组src中查找的目标值
	 * @return 首次在src中找到的、与target相等的元素的下标
	 */
	public static int search(int[] src,int taget) {
		int l=0;//左端点,初始化为原数组的最小的索引
		int r=src.length-1;//右端点,初始化为原数组的最大索引
		while(l<=r) {//说明还没有二分完毕
			int mid=l+(r-l)/2;//对给定的区间开始二分,得到数组的中点位置元素的索引
			if (taget==src[mid]) {//表示查找到目标
				return mid;//返回目标元素在原数组中索引,并结束查找,不再进行下面的操作
			}
			if (taget<src[mid]) {//说明查找目标可能在较小的区间内
				r=mid-1;//所以调整右端点的索引,使查找范围变为两个查找区间中较小的一个
			}else{//说明查找的目标可能在较大的区间内
				l=mid+1;//所以调整左端点的索引,使查找范围变为两个区间较大的一个
			}
		}
		return -1;//二分遍历完毕,在数组中都没找到与value相等的值,则返回下标-1表示未找到
	}
}

对数组{1,2,3,5,6,7,7,8,9}进行五次查找操作
		int i = search(src, 10);
		System.out.println(i);
		
		int j = search(src, 0);
		System.out.println(j);
		
		int k = search(src, 7);
		System.out.println(k);
		
		int m = search(src, 4);
		System.out.println(m);
		
		int n = search(src, 6);
		System.out.println(n);
查找结果
-1
-1
6
-1
4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bitDesigner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值