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 @   咪啪魔女  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示