Fibonacci数列

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、……

F(n)={1                                   n=0,1

           F(n-1)+F(n-2)             n>1


一、由递归算法可得:

public static int Fibonacci_Solution1(int n)
{
    if(n<=1)  return  1;
    return Fibonacci_Solution1(n-1)+Fibonacci_Solution1(n-2);
}

缺点:递归由于调用函数自身,有时间和空间的消耗,函数的调用机制可由下表示:

1 、建立栈空间

2 、保护现场(将当前主调函数的执行状态和返回地址保存在栈中)

3、为被调函数的局部变量(包括形参)分配栈空间,并将实参值传递给形参。

4、执行被调函数直至返回语句或函数结束处

5、释放被调函数的所有局部变量栈空间

6、恢复现场。取出主调函数的执行状态及返回地址,释放栈空间。


递归的本质是将一个问题分解成两个或者多个小问题,如果小问题存在相互重叠的部分,那么就存在重复的计算。

递归还可能引起:调用栈溢出。每一次调用函数都在内存栈中分配空间,而每个进程的栈的容量是有限的。当递归调用的层级太多时,就会超出栈的容量。


二、迭代法(避免重复计算,保留中间项,从下往上)

long 和 int 范围是[-2^31,2^31-1],即-2147483648~2147483647,而unsigned范围是[0,2^32-1],即0~4294967295,所以常规的32位整数只能够处理40亿左右,当遇到比40亿大的多的数就要用到64位。 long long / unsigned long long 一般是Linux下申明方式、如:G++。

windows下需要用long long或,__int64配合%I64d。而在UNIX、Linux中必须使用标准C规定的long long配合%lld。

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "iostream"
using namespace std;
// ====================方法2:循环====================
long long Fibonacci_Solution2(unsigned n)
{
    int result[2] = {0, 1};
    if(n < 2)
        return result[n];

    long long  fibNMinusOne = 1;
    long long  fibNMinusTwo = 0;
    long long  fibN = 0;
    for(unsigned int i = 2; i <= n; ++ i)
    {
        fibN = fibNMinusOne + fibNMinusTwo;

        fibNMinusTwo = fibNMinusOne;
        fibNMinusOne = fibN;
    }

     return fibN;
}

int _tmain(int argc, _TCHAR* argv[])
{
	long long a= Fibonacci_Solution2(100);
	printf("%I64u\n",a);
	//std::cout<<a<<endl;
	system("pause");
    return 0;
}
迭代法的时间复杂度为O(n),使用的内存空间也不会动态上涨。


三、通项公式法

F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}

具体推导过程可参考:1、http://baike.baidu.com/link?url=nVfTTJJdRBbCsaNWnL0IZInkk8RCDrfqVtJKFQEf98H9L0lDV6zAxBFuch_Cg0cU

                                        2、http://blog.163.com/zhuxun2@126/blog/static/3631555720071024105814506/

function y = Fib(n)
sr5 = sqrt(5);
y = uint32((((1 + sr5) / 2) ^ n - ((1 - sr5) / 2) ^ n) / sr5);
end
 该方法的时间复杂度貌似为O(1),但我们还应该考虑乘方运算的时间消耗。不加特别优化时,用乘法实现n次乘方的时间复杂度为O(n)。考虑到浮点数计算效率和精度问题。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值