二分法之位运算 快处理

本文详细介绍了二分查找法的基本原理,展示了其在有序数组中的高效查找过程,并通过JDK源码剖析了位运算优化的技巧。同时,提供了一段基于JDK代码的实战示例,探讨了如何在实际编程中应用和优化二分查找。

二分法 升级优化

一、 二分法

二分查找是一种在数组中查找数据的算法。和线性查找不同,它只能查找已经排好序的数据。二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边。因此,比较一次就可以把查找范围缩小一半。重复执行该操作就可以找到目标数据,或得出目标数据不存在的结论。二分查找利用已排好序的数组,每一次查找都可以将查找范围减半。查找范围内只剩一个数据时查找结束。数据量为 n 的数组,将其长度减半 log2n 次后,其中便只剩一个数据了。也就是说,在二分查找中重复执行“将目标数据和数组中间的数据进行比较后将查找范围减半”的操作 log2n 次后,就能找到目标数据(若没找到则可以得出数据不存在的结论),因此它的时间复杂度为 O(logn)

二分法要比线性查找要快因为线性查找的时间复杂度为O(n),二分法首先要保证数组是按照升序序排列的,如果每没有顺序结果也是无异意义的。二分法是要根据数组的开始坐标
和末尾坐标来选取中间的坐标,此时可以先将这个求出的坐标当做“指针”,之后根据查找的值和中间的值进行比较 如要是经比较中间的值大于查找的值那么求出的“指针” 要左移,否则要右移。而中间的下标如何求呢?这个或许是很简单的 用(开始 +数组.length)/2 即可得出,但是通过看JDK的源码对二分法处理中间下标是根据位运算得出的,想想这个是为啥呢?因为位运算要比计算要快 而且对于数值过大也不会因为int的最大值而影响。

 public static <T>
    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            return Collections.indexedBinarySearch(list, key);
        else
            return Collections.iteratorBinarySearch(list, key);
    }

    private static <T>
    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
        int low = 0;
        int high = list.size()-1;

        while (low <= high) {

            int mid = (low + high) >>> 1; //代替(low + high) / 2
            Comparable<? super T> midVal = list.get(mid);
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found
    }

二 、代码

   经过上面JDK的源码的学习对二分法有进行了修改如下
 public int binarySearch1(long value,long [] arr) {
        int low = 0;
        int high = length-1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            if (arr[mid] > value) {
                high = mid-1;
            }else  if(arr[mid] < value) {
                low = mid+1;
            }else {
                return mid;
            }
        }
        return -(low + 1);
    }
在这里插入代码片
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值