斐波那契数的实现与改进

什么是斐波那契数

定义:

斐波那契数为第一个数和第二个数是1,从第三个数开始为前两个数之和,数学表达式为:
当N<3时,f(N) = 1;
当N=>3时,f(N) = f(N-1)+f(N-2);

代码实现:

1、递归实现:

 int Fib(int n)
{
    int First = 1;
    int Second = 1;
    int ret = 0;
    if (n<3)
    {
        return 1;
    }
    else
    {
        return Fib(n - 1) + Fib(n - 2);
    }
}

时间复杂度:O(n)=递归次数(n-1)*基本操作1=n;
空间复杂度:O(n)=递归次数(n-1)*创建对象个数为常数 = n

2、非递归实现:

int Fib(int n)
{
    int First = 1;
    int Second = 1;
    int ret = 0;
    if (n<3)
    {
        return 1;
    }
    while (n > 2)
    {
        ret = First + Second;
        First = Second;
        Second = ret;
        n--;
    }
    return ret;
}

时间复杂度:O(n)=n,运行次数为n次;
空间复杂的;O(n)=O(1),创建对象都为常数项

所存在的缺陷:

当N为一个非常大的数时,那么使用递归调用的时间复杂度是非常大的,执行的效率也是非常的差。

代码改进:

long long Fib(long long first, long long second, long N)
{
    if(N < 3)
    {
        return 1;
    }
    if(3 == N)
    {
        return first+second;
        return Fib(second, first+second, N-1);
    }
}

这里的long long 类型是在当你递归很大值时防止内存不够而溢出,
尾递归就是在递归函数中,递归调用返回的结果被直接返回
递归方式总是以二叉树一样在栈上以指数形式增长,耗费时间大,
尾递归方式以类似于循环方式以线性增长,在尾递归时,调用自身的同时直接计算参数。

总结:

尾递归的本质是:将每次计算的结果缓存起来,传递给下次调用,相当于自动累积,节省了计算时间,并且在有的编译器中通常都会对尾递归进行优化。编译器会发现根本没有必要存储栈信息了,因而会在函数尾直接清空相关的栈。

猜你喜欢

转载自blog.csdn.net/zl_8577/article/details/78764169
今日推荐