查找——折半查找

源码文件在这里下载


前言

折半查找是一种基础的查找算法,本文主要介绍了折半查找算法的思路、算法实现,并辅以图示,希望读者可以清晰的理解算法步骤。不足之处欢迎评论区指出。


一、算法思路

算法能够实现查找是基于数组有序这一前提的,对于无序的数组,折半查找并不能起到作用。在有序数组中,通过不断寻找中点元素并与目标元素对比一步步缩小查找区间,最终确定目标元素是否存在于数组之中。

二、算法实现

    public static boolean binarySearch(int[] data,int target){
        int bottom = 0;
        int top = data.length-1;
        while(bottom <= top){
            int midpoint = (top + bottom)/2;
            if (target == data[midpoint]){
                return true;
            } else if (target < data[midpoint]) {
                top = midpoint - 1;
            } else {
                bottom = midpoint + 1;
            }
        }
        return false;
    }

三、算法图示

在数组data上演示折半查找,以元素7669为例。(元素69并未存在于数组data中)

		int[] data = {2,9,11,15,28,33,40,47,51,64,76,77,82,85,94};

通过下面的代码运行折半查找,查找元素76并打印查找结果。

	    boolean b = binarySearch(data, 76);
	    System.out.println(b);

折半查找元素76
图中黄色区域,表示当前查找区间;红色高亮表示bottom位置,蓝色高亮表示top位置,绿色高亮表示bottom与top重合,向下的黑色箭头表示中点位置。右侧表格中红色箭头、蓝色箭头标识查找区间上界或下界的变化。

通过下面的代码运行折半查找,查找元素69并打印查找结果。

	    boolean c = binarySearch(data, 69);
	    System.out.println(c);

折半查找元素69

四、算法步骤

1.输入输出

输入待查找的数组,以及查找目标。
输出判断查找目标是否存在于待查找数组中,存在返回true,不存在返回false。如果需要返回下标等信息,可以自己另做修改。

 public static boolean binarySearch(int[] data,int target){}

2.变量初始化

折半查找的“半”怎么查找呢,通过数组的开始元素和最后一个元素的位置来确定。因此需要首先确定botttom:开始位置top:结束位置。初始化时,对于待查找数组,开始位置就是开始元素的下标0,结束位置就是最后一个元素的下标data.length-1(数组长度减一)。

        int bottom = 0;
        int top = data.length-1;

3.查找终止条件

查找有两个出口。一个是循环执行完毕,仍然没有发现目标元素,此时查找终止。另一个是在查找过程中找到了目标元素,提前结束循环,返回结果,查找终止。

		while(bottom <= top){
			...
			return true;
			...
		}

4.折半的“半”

计算bottomtop的均值得到中点的位置。此时注意,除数为整数,得到的结果向下取整,也就是做地板(floor)函数处理。

		int midpoint = (top + bottom)/2;

5.缩小查找区间

如果中点位置即是目标元素,则返回结果,查找结束。如果中点位置不是目标元素,基于数组元素有序且从小到大排列这一前提,如果目标元素小于中点元素,则说明应该向左查找,因此将原查找区间缩小至中点元素左半区间。同理,当目标元素大于中点元素时,将原查找区间缩小至中点元素右半区间。值得注意的是,因为在第一步中已经比对了中点元素的值,因此在top = midpoint - 1bottom = midpoint + 1执行的减一和加一操作,是去掉了已经比对过的中点元素,使得查找区间进一步缩小。

            if (target == data[midpoint]){
                return true;
            } else if (target < data[midpoint]) {
                top = midpoint - 1;
            } else {
                bottom = midpoint + 1;
            }

总结

算法的思路比较简单,重在对于诸多细节的把握。厘清脉络、注意细节,实现起来就会容易许多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值