1. 程式人生 > >【演算法筆記】二分法的使用(使用目的+模板)

【演算法筆記】二分法的使用(使用目的+模板)

今天看完《演算法筆記》裡二分法這個章節,稍微總結一下。

二分法的思想主要就是折半查詢,達到O(logn)的查詢速度。

使用目的或者說使用情景主要有如下三個,下面將依次介紹。

  1. 查詢有序序列中是否存在滿足條件的元素
  2. 查詢有序序列中滿足條件的第一個元素
  3. 對一些函式進行求根(近似)計算

1. 查詢有序序列中是否存在滿足條件的元素

下面的函式是找到a[]陣列中是否有等於x的元素,如果有返回索引下標,如果沒有則返回-1。

要注意二分的使用條件是序列有序,下面程式碼中的判斷條件可以根據使用需求進行修改。

對於一些下標快達到int上限的搜尋區間時,可以把

mid = (left + right) / 2;

替換為

mid = left + (right - left) / 2;
int binary_search(int a[], int left, int right, int x) {
    int mid;
    while (left < right) {
        mid = (left+right) / 2;
        if (a[mid] == x) return mid;
        if (a[mid] > x) { // 可以根據具體使用需求修改條件
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return -1;
}

2.查詢有序序列中滿足條件的第一個元素

下面的函式是找到a[]陣列中等於x的第一個元素的索引下標。

同樣的,程式碼中的判斷條件可以根據使用需求進行修改。

int binary_search(int a[], int left, int right, int x) {
    int mid;
    while (left < right) {
        mid = (left+right) / 2;
        if (a[mid] >= x) { // 條件可以根據需求進行修改
            right = mid;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

3.對一些函式進行求根(近似)計算(求根號2近似值為例)

const int eps = 1e-5; // 求根精度為1e-5
double f(double x) {
    return x*x-2;
}
int solve(double L, double R) { // L R為求根區間
    int l = L, r = R, mid = (l + r) / 2;
    while (r - l < eps) {
        mid = (l + r) / 2;
        if (f(mid) > 0) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    return mid;
}