一、二分查找

     1)、查找的数组或者集合必须是有序的,倒序或者升序均可。

     2)、实现思路是:将需要查找的集合或者数组对半均分,每次循环只需要对比数组中间位置的Value是否大于需要查找的Value,大于则取前半部分小于就取后半部分。
     3)、数组或者集合中可能存在重复元素,按照以下逻辑无法完全找到所有该Value对应下标。

              (1):可以考虑循环将已经找的下标向左或者向右+1获取对应Value再做对比,直到找完所有重复元素下标

              (2):如果对数据要求没有那么高,可以考虑使用Set集合去除重复元素排序之后,再做查找

/**
     * 循环实现二分查找
     * @param a
     * @param val
     * @return
     */
    public static int binarySearch(int[] a,int val) {
        if(a.length <= 0) {
            return -1;
        }
        int lo = 0;//开始下标位置
        int hi = a.length-1;//最高下标位置,取最后一位
        while(lo <= hi) {//当 lo <= hi时,证明该数组里面已经查询完成
            int temp = lo + (hi - lo)/2;//获取数组中间的下标位置
            //如果当前查询val大于数组中间值则开始的下标向右边移动变成(lo =  temp+1)中间下标对应的值不进入下次循环
            if(val > a[temp] ) {
                lo = temp+1;
            //如果当前查询val小于数组中间值则最高位置的下标向左边移动变成(hi =  temp-1)中间下标对应的值不进入下次循环
            }else if(val < a[temp]) {
                hi = temp -1;
            }else {
                //相等就返回当前的下标
                return temp;
            }
        }
        return -1;
    }

 

/**
     * 递归实现二分查找
     * @param arr
     * @param lo
     * @param hi
     * @param val
     * @return
     */
    public static int binarySearch(int[] arr,int lo,int hi,int val) {
        if(arr.length == 0) {
            return -1;
        }
        
        if(lo <= hi) {
            int mid = lo + (hi - lo)/2;
            if(val > arr[mid]) {
                return binarySearch(arr,mid+1,hi,val);
            }else if(val < arr[mid]) {
                return binarySearch(arr,lo,mid-1,val);
            }else {
                return mid;
            }
        }else {
            return -1;
        }
    }