java二分查找,折半查询算法

二分查找是一个较为简单的查找算法.要求所查数据集合必须为有序的.也因此,注定了这种数据结构在插入方面的xing性能很差(因为要移动引用位置,腾出空间来,在javali里面,由于数据存的是引用.所以影响不大);

具体思路是: 在一个有序集合中,确定中间位置的值middleIndex位置.然后这个位置的值和要查询的目标target进行比较, 如果小于target,说明middleIndex位置左边的数都小于target.那么将开始位置的下标设置为middleIndex. 即startIndex=middleIndex; 然后再来根据新的startIndex和endIndex算出一个新的middleIndex值. 如果target小于middleIndex位置的值.说明middleIndex右边的数都是大于target的.那么将endIndex设置为middleIndex. 重复上面的操作, 直到2者相等或者startIndex=endIndex...  

然后补充下上面逻辑会漏掉的情况,就是集合里面只有一个数的情况. 这种情况下单独抽离出来;

-------------------------------------------------

上面那种查找针对的是集合里面不会有重复数据的情况. 如果有重复数据, 那么在第一次找到target的时候, 后面继续用二分查找很不划算(因为在有序集合中,相同的数一定是相邻的), 所以这种情况下, 只需将middleIndex -1 或者middleIndex + 1就可以了;同时,这种方法还不会重复查找已经找到过的数据.

public void binarySearch() {
//        int[] a = new int[] {1,2,3,7,7,7,7,8,9};
        int[] a = new int[]{7,7,7,7,7,7,7,7,7,7};
        int target = 7;
        int startIndex = 0;
        int endIndex = a.length - 1;
        int middleIndex = (startIndex + endIndex) / 2;
        /** 重复值查询逻辑*/
        int lowIndex = 0;
        int upperIndex = 0;
        while (startIndex < endIndex && startIndex < middleIndex) {
            if (target > a[middleIndex]) {
                startIndex = middleIndex;
                middleIndex = (startIndex + endIndex) / 2;
            } else if (target < a[middleIndex]) {
                endIndex = middleIndex;
                middleIndex = (startIndex + endIndex) / 2;
            } else {
                System.out.println(middleIndex);
                /** 有重复值查询逻辑*/
                lowIndex = middleIndex;
                upperIndex = middleIndex;
                while (startIndex <= middleIndex - 1) {
                    middleIndex = middleIndex - 1;
                    if (target == a[middleIndex]) {
                        System.out.println(middleIndex);
                    }
                }
                middleIndex = upperIndex;
                while (endIndex >= middleIndex + 1) {
                    middleIndex = middleIndex + 1;
                    if (target == a[middleIndex]) {
                        System.out.println(middleIndex);
                    }
                }
                return;
            }
        }
        /** 只有一个数的情况*/
        if (target == a[middleIndex]) {
            System.out.println(middleIndex);
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值