http://blog.csdn.net/yangalbert?viewmode=contents
Fibonacci(斐波那契)数列定义:
(1)递归实现
思想简单,无需赘述,实现如下:
- // 递归方法复杂度O(2^n),计算到n=41已达到计算机的极限
- int F( int n )
- {
- if ( n <= 0 ) return 1;
- else if ( n == 1 ) return 1;
- else return F(n-1)+F(n-2);
- }
- int* Fibonacci1( int len )
- {
- int* arr = (int*)malloc( sizeof(int) * len);
- if ( arr == NULL ) return arr;
- for ( int i = 0; i < len; ++i ) arr[i] = F(i);
- return arr;
- }
该方法存在很多重复计算,虽然是典型的递归,但效率很低,资源消耗大。经分析,改算法时间复杂读为指数阶(O(2^n)),远高于多项式阶;占用计算机空间资源大,经测试在n=41时已达到PC的极限。
(2)采用通项公式计算
递推公式为x(n+2)=x(n+1)+x(n),是一个二阶常系数齐次线性差分方程,利用该差分方程的特征方程t^2=t+1,以及初始条件x(0)=1, x(1)=1易解出x(n)的通项表达式。
f(n)的通项表达式:
C实现:
- struct data
- {
- double f1;
- double f2;
- };
- // 利用通项公式计算,时间复杂度O(n)
- int* Fibonacci2( int len )
- {
- const double sqrt_5 = sqrt(5.0);
- const double p1 = (1+sqrt_5)*0.5;
- const double p2 = (1-sqrt_5)*0.5;
- data d = {(1+1.0/sqrt_5)/2.0, (1.0/sqrt_5-1)/2.0};
- int* arr = (int*)malloc( sizeof(int) * len);
- if ( arr == NULL ) return arr;
- for ( int i = 0; i < len; ++i )
- {
- arr[i] = (int)(d.f1-d.f2+0.5);
- d.f1 *= p1;
- d.f2 *= p2;
- }
- return arr;
- }
虽然采用通项公式的算法能以O(1)的时间复杂度计算Fibonacci数列,但引入了浮点数,计算精度无法保证。
(3)采用二阶递推的方法
注意到,存在矩阵A=(1,1;1,0)使得下式成立
据此得到Fibonacci数列的实现代码:
- // 用于迭代操作的2x2矩阵
- class matrix
- {
- public:
- matrix():a(1),b(1),c(1),d(0){}
- matrix(int a1, int b1, int c1, int d1):a(a1),b(b1),c(c1),d(d1){}
- matrix( const matrix& B ):a(B.a),b(B.b),c(B.c),d(B.d){}
- const matrix& operator*=( const matrix& B)
- {
- int a1 = a, b1 = b, c1 = c, d1 = d;
- int a2=B.a, b2=B.b, c2=B.c, d2=B.d;
- a = a1 * a2 + b1 * c2;
- b = a1 * b2 + b1 * d2;
- c = c1 * a2 + d1 * c2;
- d = c1 * b2 + d1 * d2;
- return *this;
- }
- unsigned int a;
- unsigned int b;
- unsigned int c;
- unsigned int d;
- };
- const matrix operator*( const matrix& A, const matrix& B)
- {
- matrix C(A);
- C *= B;
- return C;
- }
- void printMatrix( const matrix& A )
- {
- printf("%d %d\n", A.a, A.b);
- printf("%d %d\n", A.c, A.d);
- }
- matrix matrixPower( const matrix& A, int n )
- {
- matrix m(1,0,0,1); // 单位矩阵
- matrix temp(A);
- for ( ; n > 0; n >>= 1 )
- {
- if ( n&1 ) m *= temp;
- temp *= temp;
- }
- return m;
- }
- int F3(int n)
- {
- matrix B(1,1,1,0);
- matrix A = matrixPower( B, n-1 );
- return A.a + A.c;
- }
- int* Fibonacci3( int len )
- {
- int* arr = (int*)malloc( sizeof(int) * len );
- if ( arr == NULL ) return arr;
- for ( int i = 0; i < len; ++i )
- {
- arr[i] = F3(i);
- }
- return arr;
- }