二分查找不同需求的多种写法(java总结)

第一种 基础版

二分查找就是创建两个索引,i和j取他们的中间值m,每次查找m这样就会比遍历节省一半的时间。

两个索引分别在首和尾,if判断要找的target在arr[m]的左边还是右边,如果小于arr[m]那么尾索引j就等于m+1,如果大于就改变首索引。如果等于就返回查到的索引,如果没找到就返回-1.

public static int Foundation(int [] arr,int target){
        int i = 0,j = arr.length - 1;
        while(i <= j){
            int m = (i + j) >>> 1;
            if(target < arr[m]){
                j = m - 1;
            }else if(target > arr[m]){
                i = m + 1;
            }else{
                return m;
            }
        }
        return -1;
    }

第二种 改进版

在基础版上进行了三处代码的改动

第一点:

对光标j的定义从arr.length - 1改成了arr.length这样就变成了左闭右开的情况

 在这种情况下永远访问不到j的位置所以循环的判断条件变成了i < j就是为了避免数组索引越界异常

第二点:

循环的判断条件

第三点:

 j改变的值

public static int improvement(int [] arr,int target){
        int i = 0,j = arr.length;   //第一点改动
        while(i < j){              //第二点改动
            int m = (i + j) >>> 1;
            if(target < arr[m]){
                j = m;            //第三点改动
            }else if(arr[m] < target){
                i = m + 1;
            }else{
                return m;
            }
        }
        return -1;
    }

第三种 平衡版

前面两种在查找次数是n的情况下,如果target在左边那么if判断的次数就是n次,因为不会加入else if进行第二次判断。但是如果target值在右边,那么if判断的次数就是2n。平衡板就是在原来的基础上优化了算法,不管在左边还是右边都是一次判断,节省了时间,但是如果是最优的情况第一次m就等于target那么效率不如上面两种,但是属于极少数情况属于也不算缺点。

在循环里面不再是找到等于target的值,而是缩小范围,当就剩一个的时候去判断是否等于target,如果等于返回该元素的索引i,否则返回-1.

public static int balance(int [] arr,int target){
        int i = 0,j = arr.length;
        while(1 < j - i){
            int m = (i + j) >>>1;
            if(target < arr[m]){
                j = m;
            }else{
                i = m;
            }
        }
        if(target == arr[i]){
            return i;
        }else{
            return  -1;
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值