6、二分查找

/**
 *二分查找:要求数组必须是有序的,也就是从小到大或者从大到小
 *
 */
public static void main(String[] args){
    int[] arr={1,2,5,6,18,19,29};
    int findIndex=binarySearch(arr,0,arr.length-1,2);
    System.out.println(findIndex);
}
public static int binarySearch(int[] arr,int left,int right,int findVal){
    //先判断当left>right时,说明没有找到
    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,right-1,findVal);
    }else{
       //等于中间值,返回中间值的下标;
       return mid;
    }
}





/**
 *在二分查找中,当有多个重复值的时候,如何进行查找
 *有重复值,这里采用集合的方式来返回,其实和找一个值差不多,最主要的是找到值后的不同
 */
public static List<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{
       //执行到这里说明值已经找到了,然后就是判断是不是多个值了
       //当有多个值的时候,先等下返回,放在集合中
       List<Integer> retIndexList=new ArrayList<Integer>();
       int temp=mid-1;//看左边有没有相同的值
       while(true){
          if(temp<0||arr[temp]!=findVal){
             break;//说明没有了
          }
          //如果没有break,说明有值,添加进集合中
          retIndexList.add(temp);
          temp-=1;//再向左查一个下标
        }
       //把中间的值加进去,也就是刚开始找到的值
       retIndexList.add(mid);

       //然后再看右边有没有相同的值
       temp=mid+1;
       while(true){
          if(temp>arr.length-1||arr[temp]!=findVal){
             break;//右边没有了,跳出循环
          }
          retIndexList.add(temp);
          temp+=1;
       }
       
    }
        //执行到这,整个方法结束,进行返回
    return retIndexList;
}

 

上一篇:二分查找


下一篇:7、插值查找