栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

二分法及其注意事项(查找数字,区间,快速幂)(C语言)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二分法及其注意事项(查找数字,区间,快速幂)(C语言)

首先介绍最基本的,所谓二分法就是把数组的元素砍成两半进行查找,前提是必须是有序数组。

时间复杂度为O(logn)。相比于遍历数组逐项查找,时间复杂度更低。

        二分法需要左,中,右三项,通过用中间项对比被查找数字,判断是从左边还是从右边缩小范围(详见代码)

#include "stdio.h"
int cmp(const void*e1,const void *e2)//排序
{
    return *((int *)e1)-*((int *)e2);
}
int search(int m,int *num,int N)
{
    int right=0,left=N-1;
    while(right<=left)//当左边等于右边的时候查找就结束了
    {
        int mid=(right+left)/2;
        if(mnum[mid])//中间项小于说明他在靠左边
        right=mid+1;//从右边缩小范围
        else return mid;//找到了返回
    }
    return -1;//查找结束,没有返回数字
}
int main()
{
    int n;
    printf("请输入数字的个数n");
    scanf("%d",&n);
    int num[n];
    for(int i=0;i 

        二分法查找范围 eg:要在一个数组中查找一个数的所处的范围(数组中可能会含有重复的数字)

查找范围意味着有左右区间,这里我们要求是左闭右开区间,要分为两个步骤,1是查找左区间,2是查找右区间。

 

查找左区间

int searchleft(int m,int *num,int N)
{
    int left=0,right=N-1;
    while(left=m)
        right=mid;
        else 
        left=mid+1;
    }
    return left;
}

查找右区间

int searchright(int n,int *num,int N)
{
    int left=0,right=N-1;
    while(leftn)
        right=mid;
        else
        left=mid+1;
    }
    return left;
}

(左边)这里面while的执行标志没有了“=”相比于查找数字,因为我们要的的是返回区间的左区间,找到了的情况是(也就是最后确定下来的值,直接返回的话就会有数字没有包含到)left=right,而查找的情况则是:只要找到了就返回,没找到就另外返回。确定右区间同理。

 这里我们需要注意一个问题(以左区间为例):

int mid=(left+right)/2;
        if(num[mid]>=m)
        right=mid;
        else 
        left=mid+1;

在写的时候我们可能会有疑问:问什么num[mid]不是>m而是>=m呢?

由此产生的代码如下

int mid=(left+right)/2;
        if(num[mid]>m)
        right=mid-1;
        else 
        left=mid;

看上去好像很合理,的确在针对一部分数据时的确可以处理,但是有例外:如果left=4,right=5

则无法结束循环,因为mid始终等于4,始终执行else的语句。mid是整型的,他会忽略掉后面的小数点。

那如何解决这个问题呢?那就是不让else的条件中包含“=”这种情况(即不让left=mid执行),如第一段代码所示。

        二分法的一个应用:快速幂

条件1:如果是偶数,那么有a^b=a^b/2 * a^b/2;

        2:  如果是奇数,那么有a^b=a*a^(b-1);

#include "stdio.h"
long long bindarypow(int a,int b)
{
    if(b==0)
    return 1;
    else if(b%2==0)
    {
        long long mul=bindarypow(a,b/2);//用mul把每一次的结果统计起来
        return mul*mul;//a^b=a^b/2 * a^b/2;
    }
    else 
    return a*bindarypow(a,b-1);//a^b=a*a^(b-1);
}
int main()
{
    int a,b;
    printf("请输入底数a和指数b");
    scanf("%d %d",&a,&b);
    long int sum=bindarypow(a,b);
    printf("%ld",sum);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352597.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号