从函数的零点问题到二分法的应用

    数学是科学的皇冠,这句话一点也不假,在程序的算法应用上也是这样的。
    众所周知,当数据量很大的时候,采用二分法是非常高效的(使用二分法查找的前提是数据是排好序的,这里不作讨论)。二分法查找的原理来自于数学上的函数的零点问题,也就是求函数的近似值(近似解)。

引用我们的高中数学教材的必修一里面的内容:求f(x)的近似解,通过试验知函数f(x)在区间(a,b)上存在零点。如何找出这个零点?一个直观的想法就是,尽可能的把零点的邻域缩小,当足够小的时候,就可以用近似值代替函数的零点。下面给出步骤
1、确定区间[a,b],验证f(a)*f(b)<0,给定精度**ε**。
2、求(a,b)的中点c。
3、计算f(c)。
    0)若f(c)=0,则c就是零点
    1)若f(a)*f(c)<0,令b=c,此时零点在(a,c)区间上,
    2)若f(c)*f(b)<0,令a=c,此时零点在(c,b)区间上,
4、验证精度是否达到要求,若|a-b|<**ε**,即零点的近似值为a(或者b),若不成立,重复2-4步骤。

下图是函数f(x)=lnx+2x-6求求近似解的示例

	那么,这种每运算一次把问题减少一半的思想,就可以运用到我们的搜索算法去,即将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x。当数据量很大的时候,这种方法就体现出它的威力来了,下面给出c++的代码(偷懒一下,百度来的)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100]={1,2,3,5,12,12,12,15,29,55};//数组中的数(由小到大)
int k;//要找的数字
int found(int x,int y)
{
    int m=x+(y-x)/2;
    if(x>y)//查找完毕没有找到答案,返回-1
        return -1;
    else
    {
        if(a[m]==k)
            return m;//找到!返回位置.
        else if(a[m]>k)
            return found(x,m-1);//找左边
         else
            return found(m+1,y);//找右边
    }
}
int main()
    {
        cin>>k;//输入要找的数字c语言把cin换为scanf即可
        cout<<found(0,9);//从数组a[0]到a[9]c语言把cout换为printf即可
        return 0;
    }

高一所学的数学都能在算法上发挥如此大的威力,不得不感叹,数学真美。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值