二分查找 (java版)

概述

二分查找(Binary Search)是一种在有序数组或列表中查找元素的快速有效的算法。二分查找通过反复将搜索区间划分为两半,并在其中之一中搜索目标元素,直到找到目标元素为止。

使用前提

  1. 有序数组:二分查找只适用于有序数组,即数组中的元素按照升序或降序排列。

  2. 随机访问能力:二分查找需要能够随机访问数组中的元素,即可以通过索引快速访问任意位置的元素。

  3. 元素比较可行:需要能够比较数组中的元素大小,确定目标元素与中间元素的大小关系,以确定查找范围的左右边界。

代码实现

//二分查找,找到返回对应索引,找不到返回-1
    public int binarySearch(int [] ints , int target){
        //先定义最大最小索引
        int min = 0;
        int max = ints.length - 1 ;

        //循环条件为min和max之间还有元素(包括端点),此处必须加等号
        while (min <= max){
            int index = (min + max) / 2;//中间位置对应索引(向下取整)
            int searchNum = ints[index];//中间位置对应值
            if (target < searchNum){//说明taget在查找中间值左侧
                max = index - 1;//让最大索引变为上一次比较的中间索引-1
            } else if (searchNum < target) {//说明target在中间值的右边
                min = index + 1;//让最大索引变为上一次比较的中间索引+1
            } else {
                return index;//说明查找值就是中间值
            }
        }
        return  -1;//当所有范围之间没有值的时候说明没找到;返回-1

    }

问题:

java对数字的储存是保留符号位的,最高位为符号位,正数为0,负数为1,当两个特别大的正数相加进位到符号位,则会产生相加结果为负数的情况,那么在求中间索引的时候会得到index为负数的情况

int index = (min + max) / 2;//中间位置对应索引(向下取整)

改进方法:将求中间索引的算法改为

int index = (min + max) >>> 1 ;//中间位置对应索引(向下取整)

这样就可以保留最高位为0并且得到除以2向下取整的效果

应用:找到某元素第一次出现的位置

   public int binarySearch(int [] ints , int target){
        //先定义最大最小索引
        int min = 0;
        int max = ints.length - 1 ;
        int result = -1;

        //循环条件为min和max之间还有元素(包括端点),此处必须加等号
        while (min <= max){
            int index = (min + max) >>> 1;//中间位置对应索引(向下取整)
            int searchNum = ints[index];//中间位置对应值
            if (target < searchNum){//说明taget在查找中间值左侧
                max = index - 1;//让最大索引变为上一次比较的中间索引-1
            } else if (searchNum < target) {//说明target在中间值的右边
                min = index + 1;//让最大索引变为上一次比较的中间索引+1
            } else{
                result = index;//说明找到了,索引留着候选
                max = index - 1;//缩小范围在前一半
            }

        }
        return  result;//返回结果

    }

找到最后一次出现的结果也是类似,只用将else中的内容改为

 result = index;//说明找到了,索引留着候选
 min = index + 1;//缩小范围在后一半

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值