1. 程式人生 > >幾種情況的二分寫法

幾種情況的二分寫法

之前總是對二分的邊界問題把握的不是很好,以致於出現死迴圈等問題。所以用這篇博文進行總結。
首先,本文所用演算法均為左閉右閉的演算法,且陣列是以非遞減順序排列的。
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]