二分查找以及算法优化版二分查找,自适应的插值查找


算法思路:


1.由数组的左右边界生成中间节点。

2.判断中间节点的值和需要查找的数值是否一致。

3.不断调节mid位置,递归的进行二分查找。

4.1查找到相等的值时,返回其下标。

4.2对于扩展二分,查找到数值时,向mid左侧遍历,如果还有此值,将此下标放入ArrayList中,然后将mid下标放入ArrayList,然后向mid右侧遍历,如果还有此值,将此下标放入ArrayList中,最后返回ArrayList。

插值查找:

插值查找适用于数据量较为庞大的有序且较为均匀的数组,利用基于二分查找加上自适应的方法查找:

利用自适应公式:

在递归出口判断处加上如下判断,一方面是为了防止进行不合法的搜索,另一方面也是为了防止之后利用上述公式计算时数组越界(value可能是一个很大的值,加入乘法计算很危险):


 

算法代码:


如下的quickSort函数为上一篇博客写的快速排序,将数组排序后,再进行二分查找。

以下为两种二分查找。

 插值查找只需要将mid计算公式换成上述自适应公式,并且修改递归出口条件即可。

public class BinarySearch {

    public static void main(String[] args) {
        QuickSort qs = new QuickSort();
        int[] arr = {5,43,56,6,8,20,1};
        int[] arr2 = {5,43,56,6,5,20,5};
        //对两个数组进行排序
        qs.quickSort(arr, 0, 6);
        for(int i = 0; i < arr.length; i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        qs.quickSort(arr2, 0, 6);
        for(int i = 0; i < arr.length; i++){
            System.out.print(arr2[i]+" ");
        }
        System.out.println();
        System.out.println(binarySearch(arr, 0, 6, 43));//调用第一个二分查找的函数
        System.out.println(binarySearch2(arr2, 0, 6, 5));//调用第二个二分查找的函数,针对查找有重复的数字
    }
    public static int binarySearch(int[] arr, int left, int right, int findVal){
        if(left > right) return -1;
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if(findVal > midVal){
            return binarySearch(arr, mid + 1, right, findVal);
        }
        else if(findVal < midVal){
            return binarySearch(arr, left, mid -1, findVal);
        }
        else{
            return mid;
        }
    }
    //扩展版二分,返回多个要查找的数的下标
    public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal){
        if(left > right) return new ArrayList<Integer>();
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if(findVal > midVal){
            return binarySearch2(arr, mid + 1, right, findVal);
        }
        else if(findVal < midVal){
            return binarySearch2(arr, left, mid -1, findVal);
        }
        else{
            /*思路分析:再找到mid索引值的时候,不要马上返回
            先向mid左侧扫描,将满足查找值的元素下标放入ArrayList
            然后向mid右侧扫描,将满足查找值的元素下标放入ArrayList
            将ArrayList返回
            */
            ArrayList<Integer> resIndexlist = new ArrayList<>();
            int temp = mid -1;
            while (true) {
                if(temp < 0 || arr[temp] != findVal){//退出
                    break;
                }
                //否则,就temp放入到resIndexlist
                resIndexlist.add(temp);
                temp --;
            }
            resIndexlist.add(mid);
            temp = mid + 1;
            while (true) {
                if(temp > arr.length - 1 || arr[temp] != findVal){//退出
                    break;
                }
                //否则,就temp放入到resIndexlist
                resIndexlist.add(temp);
                temp ++;
            }
            return resIndexlist;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值