常见算法之二分查找算法

二分查找算法

概念

利用每次将数据平分的思想将数据分为两部分,然后不断进行查找。这样的算法时间复杂度很低,当有X个数据的时候,最多的查找次数是n=log2X。
但是 这个算法的缺点在于只能用于有序的数组序列,如果数组无序,我们需要先将它排序才行。

理解

为了更好的理解我找了一道很经典的二分查找算法题,供大家理解: 传送门
常见算法之二分查找算法_第1张图片

思路

1.如题上所说用二分查找算法说明数组已经是一个有序的数组,那么我们就可以每次将数组分为两部分,用array[mid]与target(要找的数)进行比对做对应的处理,然后不断循环此过程,最后得出下标。
2.值得注意的是:
(1)我们可以通过递归和非递归的两种形式才解决,只不过递归的时间复杂度要很高,因为它有很多的重复计算。
(2)应题上的要求:若该元素出现多次,请返回第一次出现的位置,所以我们在写代码的时候要做出相应的处理。

代码:    

public class BinarySearch {
    //递归版本
    public static void binarySearch(int[] array,int target){
        int left=0;
        int right=array.length-1;
        System.out.println(rec_binarySearch1(array, left, right, target));
    }
    /* 这里输出的时候因为要满足题意若该元素出现多次,请返回第一次出现的位置。
       所以我们要进行判断
       */
    public static int rec_binarySearch1(int[] array,int left,int right,int target){
        int mid=(left+right)>>1;
        if(left>right){
            return -1;
        }
        //第一种:结合它是有序数组排除特殊特殊情况进行判断:这里可能会不太好理解
        if(array[mid]==target&&(mid==left||array[mid-1]!=target)){
        //mid==left结合只有两个一样的数据来想
        //array[mid-1]!=target 结合数组是有序的来想
            return mid;
            }
        if(array[mid]>=target){  //这里是  >=   因为如果不写=的话上边的那个if判断没成功就只能返回-1了
            return rec_binarySearch1(array,left,mid-1,target);
        }else if(array[mid]<target) {
            return rec_binarySearch1(array,mid+1,right,target);
        }
        return -1;
    }
    public static int rec_binarySearch2(int[] array,int left,int right,int target){
        int mid=(left+right)>>1;
        if(left>right){
            return -1;
        }
        if(array[mid]>target){  //这里是  > 因为等于的情况下边会进行处理
            return rec_binarySearch2(array,left,mid-1,target);
        }else if(array[mid]<target) {
            return rec_binarySearch2(array,mid+1,right,target);
        }
        //第二种:如果出现多次target,遍历一下数组a获得第一个value的数组下标返回即可
        for(int i=0;i<array.length;i++){
            if(array[i]==target){
                return i;
            }
        }
        return -1;
    }
    //迭代版本
    public static int ite_binarySearch(int[] array,int target){
        int left=0;
        int right=array.length-1;
        while(left<=right){ //这里要有= ,否则(如果恰好这里有我们要返回的数据),错过了left==right这里会直接返回-1
            int mid=(left+right)>>1;
            if(array[mid]==target&&(mid==left||array[mid-1]!=target)){
                return mid;
            }else if(array[mid]>=target){
                right=mid-1;  //说明想要的数在array[mid]的左边(array是个升序数组)
            }else{
                left=mid+1; //说明想要的数在array[mid]的右边(array是个升序数组)
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] array={4,4,10,21};
        //binarySearch(array,4);
        System.out.println(ite_binarySearch(array,4));
    }
}

你可能感兴趣的:(数据结构,算法题集锦,Java)