算法

二分查找-扩展


二分查找

二分查找是一个基础算法,基本思想就是将查找的键和子数组的中间键作比较,如果查找的键小于中间键,那么在左子数组继续查找;如果大于中间键,那么在右子数组中查找,否则中间键就是要查找的元素。 CODE ⇩⇩⇩

int binarySearch(const int *arr,int n,int key){
    int lo = 0,hi = n-1;
    while(lo <= hi){
        int mid = lo + (hi-lo)/2;
        int cmp = arr[mid] - key;
        if(cmp == 0) return mid;
        if(cmp < 0) lo = mid +1;
        else hi = mid - 1;
    }
    return -1;
}

注意点: 判断条件必须是lo<=hi,否则判断条件不完整。

二分查找的变种

如果二分查找的条件发生变化,比如:数组中的元素重复,要求返回匹配的数据的最大或最小下标;更进一步,需要找出数组中第一个大于Key的元素(最小的大于Key的元素)下标。 实现的主体代码不发生变化,主要就是判断条件的变化(边界条件)

查找第一个与Key相等的元素

有重复值,找到等于Key的最左边元素的下标

int binarySearch(const int *arr,int n,int key){
    int lo = 0,hi = n-1;
    while(lo <= hi){
        int mid = lo + (hi-lo)/2;
        int cmp = arr[mid] - key;
        if(cmp < 0) lo = mid +1;
        else hi = mid - 1;
    }
    if(lo < n && arr[lo] == key) return lo;
    return -1;
}

查找最后一个与Key相等的元素

多重复值,找到等于Key的最右边元素的下标

int binarySearch(const int *arr,int n,int key){
    int lo = 0,hi = n-1;
    while(lo <= hi){
        int mid = lo + (hi-lo)/2;
        int cmp = arr[mid] - key;
        if(cmp > 0) hi = mid - 1;
        else lo = mid +1;
    }
    if(hi < n && arr[hi] == key) return hi;
    return -1;
}

查找第一个等于或者大于Key的元素

如果有多个等于Key的值,返回最左边元素的下标; 否则返回大于Key的最左边元素下标

int binarySearch(const int *arr,int n,int key){
    int lo = 0,hi = n-1;
    while(lo <= hi){
        int mid = lo + (hi-lo)/2;
        int cmp = arr[mid] - key;
        if(cmp < 0) lo = mid +1;
        else hi = mid - 1;
    }
    return lo;
}

查找最后一个等于或者大于Key的元素

如果有多个等于Key的元素,返回最右边元素的下标;否则返回小于Key的最右边元素下标

int binarySearch(const int *arr,int n,int key){
    int lo = 0,hi = n-1;
    while(lo <= hi){
        int mid = lo + (hi-lo)/2;
        int cmp = arr[mid] - key;
        if(cmp > 0) hi = mid - 1;
        else lo = mid +1;
    }
    return hi;
}