【算法笔记】二分法的使用(使用目的+模板)

今天看完《算法笔记》里二分法这个章节,稍微总结一下。


二分法的思想主要就是折半查找,达到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;
}

 

你可能感兴趣的:(算法总结)