二分查找

落爺英雄遲暮 提交于 2019-12-15 06:41:53

二分查找:
使用场景:有序数据 存放于数组中
数据量过大也不适宜使用,因为数组占用的是连续大小的空间

作业:
有序数组中(不)存在重复元素
递归和非递归实现

思考题:
如何在 1000 万个整数中快速查找某个整数?
是否有序? 有序二分查找
无序:查找几次?
多次,先排序,后遍历查找??
一次,直接遍历


查找第一个大于等于给定值的元素
ip范围查找,二分查找,找大于等于该数的值,然后查看对应地址

练习:
查找第一个大于等于给定值的元素
非递归,精简写法 while
查找第一个小于等于给定值的元素

public class Search {

    public static void main(String[] args) {
//        int low =1,high=5;
//        int mid =  low + ((high - low) >> 1);// 避免low+high导致的溢出问题
//        System.out.println(mid);
//        System.out.println((low+high)/2);
//
//
//        int[] arr = {1,1,2,2,3,4,4,6,6,7};
//        System.out.println(binarySearch(arr,1,0,arr.length-1));

        new LinkedHashMap<>();


        int[] arr = {1,1,2,4,6,7,7,9,11,13,13};
//        System.out.println(bSearchFirstBigOrEqual(arr,-1));
//        System.out.println(bSearchFirstBigOrEqual(arr,1));
//        System.out.println(bSearchFirstBigOrEqual(arr,2));
//        System.out.println(bSearchFirstBigOrEqual(arr,3));
//        System.out.println(bSearchFirstBigOrEqual(arr,7));
//        System.out.println(bSearchFirstBigOrEqual(arr,8));
//        System.out.println(bSearchFirstBigOrEqual(arr,10));
//        System.out.println(bSearchFirstBigOrEqual(arr,13));
//        System.out.println(bSearchFirstBigOrEqual(arr,14));

        System.out.println(bSearchFirstSmallOrEqual(arr,-1));
        System.out.println(bSearchFirstSmallOrEqual(arr,14));
        System.out.println(bSearchFirstSmallOrEqual(arr,1));
        System.out.println(bSearchFirstSmallOrEqual(arr,13));


//        System.out.println(bsearch(arr,14));
//        System.out.println(bsearch(arr,-1));
//        System.out.println(bsearch(arr,1));
//        System.out.println(bsearch(arr,13));
//        System.out.println(bsearch(arr,7));
//        System.out.println(bsearch(arr,3));
//
//       System.out.println(bSearchLastEqual(arr,14));
//        System.out.println(bSearchLastEqual(arr,-1));
//        System.out.println(bSearchLastEqual(arr,1));
//        System.out.println(bSearchLastEqual(arr,13));
//        System.out.println(bSearchLastEqual(arr,7));
//        System.out.println(bSearchLastEqual(arr,3));

    }

    /**
     * desc: 查找等于给定值的元素的下标
     * arr:从小到大排序的数组,值不重复
     * v:需要查找的值
     */
    public static  int bsearch(int[] arr, int v) {
        if(null == arr || arr.length==0 ){
            return -1;
        }
        int l=0, r =arr.length-1;
        int m = l+((r-l)/2);
        while(l<=r){
            if(arr[m]>v){
                r = m-1;
            }else if(arr[m] <v){
                l = m+1;
            }else{
                return m;
            }
            m = l+((r-l)/2);
        }
        return -1;
    }

    /**
     * desc: 查找第一个等于给定值的元素的下标
     * arr:从小到大排序的数组
     * v:需要查找的值
     */
    public static int bSearchFirstEqual(int[] arr, int v){
        if(null == arr || arr.length==0 ){
            return -1;
        }
        int l = 0;
        int r = arr.length-1;
        int m = l+((r-l)>>2) ;
        while(l<=r){
            if(arr[m] > v){
                r = m - 1;
            }else if(arr[m] < v ){
                l = m+1;
            }else{
                if(m==0 || arr[m-1] != v){
                    return m;
                }else{
                    r = m-1;
                }
            }
            m = l+((r-l)>>1) ;
        }
        return -1;
    }

    /**
     * desc: 查找第一个大于等于给定值的元素
     * arr:从小到大排序的数组
     * v:需要查找的值
     */
    public static int bSearchFirstBigOrEqual(int[] arr, int v){
        if(null == arr || arr.length==0 ){
            return -1;
        }
        int l = 0;
        int r = arr.length-1;
        int m = l+((r-l)>>2) ;
        while(l<=r ){
            if(arr[m] >= v){
                if(m==0 || arr[m-1] < v){
                    return m;
                }else{
                    r = m-1;
                }
            }else if(arr[m] < v ){
                l = m+1;
            }else{
                // impossible
            }
            m = l+((r-l)>>1) ;
        }
        return -1;
    }

    /**
     * desc: 查找最后等于给定值的下标
     * arr:从小到大排序的数组
     * v:需要查找的值
     */
    public static int bSearchLastEqual(int[] arr, int v){
        int l=0,r=arr.length-1;
        int m = l+((r-l)>>1);
        while(l<=r){
            if(arr[m] < v){
                l = m+1;
            }else if (arr[m] > v){
                r = m-1;
            }else{
                if(m == arr.length-1 || arr[m+1]!=v){
                    return m;
                }else{
                    l = m+1;
                }
            }
            m = l+((r-l)>>1);
        }
        return -1;
    }

    /**
     * desc: 查找第一个小于等于给定值的元素
     * arr:从小到大排序的数组
     * v:需要查找的值
     */
    public static int bSearchFirstSmallOrEqual(int[] arr, int v){
        int l=0, r=arr.length, m=l+((r-l)>>1);

        while(l<=r){
            if(arr[m] > v){
                r = m-1;
            }else if(arr[m] <= v){
                if(m == arr.length-1 || arr[m+1] > v){
                    return m;
                }else{
                    l = m+1;
                }
            }else{
                // impossible
            }
            m = l+((r-l)>>1);
        }
        return -1;
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!