几种情况的二分写法

之前总是对二分的边界问题把握的不是很好,以致于出现死循环等问题。所以用这篇博文进行总结。
首先,本文所用算法均为左闭右闭的算法,且数组是以非递减顺序排列的。
1、查找是否存在关键值,如有相等的,则返回最左边的那个值的位置。否则,返回-1.

int binary_search_1(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) / 2);//向下取整
        if (a[m] < key) 
            l = m + 1;
        else 
            r = m;
    }
    if (a[r] == key) return r;
    return -1;
}   

2、查找是否存在关键值,如有相等的,则返回最右边那个值得位置。否则,返回-1.

int binary_search_2(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l + 1) / 2);//向上取整
        if (a[m] <= key) 
            l = m;
        else 
            r = m - 1;
    }
    if (a[l] == key) return l;
    return -1;
}

3、查找最小的比关键值大的位置。

int binary_search_3(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) / 2);//向下取整
        if (a[m] <= key) 
            l = m + 1;
        else 
            r = m;
    }
    if (a[r] > key) return r;
    return -1;
}

4、查找最大的比关键值小的位置。

int binary_search_4(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l + 1) / 2);//向上取整
        if (a[m] < key) 
            l = m;
        else 
            r = m - 1;
    }
    if (a[l] < key) return l;
    return -1;
}

5、查找最小的大于等于关键值的位置。

int binary_search_5(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) / 2);//向下取整
        if (a[m] <= key) 
            l = m + 1;
        else 
            r = m;
    }
    if (a[r] >= key) return r;
    return -1;
}

6、查找大的小于等于关键值的位置。

int binary_search_6(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l + 1) / 2);//向上取整
        if (a[m] < key) 
            l = m;
        else 
            r = m - 1;
    }
    if (a[l] <= key) return l;
    return -1;
}


另外:

1、找最小(左)的就向下取整。找最大(右)的就向上取整。

2、如果向下取整了,l+1.如果向上取整了,r-1.

3、对于带等号的情况来说。寻找最小(左)的就是key <= a[m]。寻找最大(右)的就是key >= a[m].

4、对于不带等号的两种情况,把以上括号减掉。

5、最后判断条件根据情况而定。但是如果是最小(左)的是a[r],最大(右)的是a[l]

你可能感兴趣的:(二分,算法总结文章)