Loading

BinarySearch

查找前提

有序序列

查找元素

递归实现

代码

#include<stdio.h>
int BinarySearch(int a[], int left, int right, int x)
{
    if(left > right) return -1;
    /*避免溢出:int mid = left + (right - left)/2*/
    int mid = (left+right)/2;
    if(a[mid]==x) return mid;
    else if (x < a[mid]) 
        return BinarySearch(a, left, mid-1, x);
    else if (x > a[mid]) 
        return BinarySearch(a, mid+1, right, x);
}

非递归实现(更常用)

/*二分区间左闭右闭, 传入初值为[0, n-1]*/
#include<stdio.h>
int BinarySearch(int a[], int left, int right, int x)
{
    int mid;
    while(left <= right)
    {
        mid = (left + right)/2;
        if(a[mid] == x) return mid;
        else if(a[mid] > x) right = mid - 1;
        else left = mid + 1;
    }
    return -1;
}

测试用例

int main()
{
    int a[5] = {1,2,3,4,5};
    int index = BinarySearch(a, 0, 4, 7);
    printf("%d\n", index);
    return 0;
}

拓展

求第一个大于等于x的元素的位置

代码实现

#include<stdio.h>
/*左闭右闭区间,传入初值为[0, n]*/
int lower_bound(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;
}

注意点

  • x不一定是数组中的存在元素
  • x可能插到数组末尾

返回一地个大于x的元素的位置

代码实现

#include<stdio.h>
/*左闭右闭区间,传入初值为[0, n]*/
int upper_bound(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;
}

注意点

与上例只有一'='之差

总结

/*寻找有序序列,第一个满足某条件的元素*/
/*二分区间为[0,n]:必须涵盖所有解的取值*/
int BinarySearch(int a[], int left, int right, int x)
{
    int mid;
    while(left < right)          /*left == right 意味找到唯一解*/
    {
        mid = (left+right)/2;
        if(条件)    right = mid; /*[left, mid]继续查找*/
        else  left = mid + 1;    /*[mid + 1, right]继续查找*/
    }
    return left;                 /*返回夹出来的值*/
}

其他应用

求函数零点

快速幂

递归写法

求(a^b)%m

typedef Long Long LL;
LL binaryPow(int a, int b, int m)
{
    if(b == 0) return 1;
    if(b % 2 == 1) return a*binaryPow(a, b-1,m)%m;
    else
    {
        LL n = binaryPow(a, b/2, m);
        return n*n%m;
    }
}
posted @ 2021-10-25 23:29  咪啪魔女  阅读(52)  评论(0编辑  收藏  举报