For the Fibonacci sequence, 1,1,2,3,5,8,12,... To solve the nth value, we usually use a recursive algorithm, that is, a recursive f (n) = f (n-1) +f (n-2). However, this is a very inefficient algorithm, when n reaches 41, it has to need about 1s, with the increase of N, time is the number of levels of growth.
Because the recursive algorithm has too many repeated calculations, as shown in the time t (n) = t (n-1) +t (n-2) +θ (1), you can know that T (N) has the lower bound of Ω ((3/2) n), T (n) <o (2^n), you can see that this is the magnitude of the time complexity.
The specific code is implemented as follows:
Elemtype Fibonacci (int n) { if(n==1| | n==2) return1; Else return Fibonacci (n-1) +fibonacci (n-2);}
In this case, the first thing we think of is the use of iterative method rewriting, the code is as follows:
Elemtype fibonacci_iterate (int n) { if(n==1| | n==2return1; 1 1 ; for (int j=3; j<=n;++j) { = f1+f2; = F2; = temp; } return F2;}
The iterative method has the time complexity of O (n).
In fact, the Fibonacci sequence also has an O (logn) algorithm, that is, using matrix multiplication, as shown, the formula can be proved by inductive method. Using this formula to find F (n) can be divided by the method, to find the n-th square of the matrix we only need N/2, and then the result of a matrix multiplication. If n is an odd number, we will first do this calculation for n-1, and then multiply the results with matrix matrices once. Suppose f (n) takes time t (n), t (n) = t (N/2) +θ (1), so its time complexity is O (logn).
The C language code is implemented as follows, and free drops a layer of requested memory whenever recursion returns.
Elemtype matrix[4] = {1,1,1,0}; Elemtype* Multipmatrix (elemtype *m1,elemtype *m2) {Elemtype*ret = (elemtype*)malloc(sizeof(elemtype) *4); ret[0] = m1[0]*m2[0]+m1[1]*m2[2]; ret[1] = m1[0]*m2[1]+m1[1]*m2[3]; ret[2] = m1[2]*m2[0]+m1[3]*m2[2]; ret[3] = m1[2]*m2[1]+m1[3]*m2[3]; returnret;} Elemtype* Fibonacci_matrix (intN) { if(n==1)returnMatrix; Elemtype*temp = Fibonacci_matrix (n >>1); Elemtype*ret =NULL; if(N &0x1) {ret=Multipmatrix (Multipmatrix (temp,temp), matrix);//return Multipmatrix (Multipmatrix (temp,temp), matrix); } Else{ret=Multipmatrix (temp,temp);//return Multipmatrix (temp,temp); } if(temp!=matrix) Free(temp); returnret;}//Matrix Method
For the iterative method and matrix method, when the size of n is larger, the advantage is more obvious, when I use the following test code, the time is about 0.17s, and the use of iterative method to achieve the code, when used to achieve more than 4s.
intn =1000000; Start=clock (); for(intI=0;i< +;++i) {Elemtype*temp =Fibonacci_matrix (n); printf ("%lld\n", temp[1]);//printf ("%lld\n", Fibonacci (n));//printf ("%lld\n", Fibonacci_iterate (n));} end=clock (); DoubleT = ((Double) (End-start))/Clk_tck; printf ("%f", t);
In summary, if our n is not very large, then we can use iterative method, because this algorithm is relatively easy to implement. When n is large, it is best to use the matrix method, of course, at this time F (n) has already exceeded the range of the C language long long, need to find ways to achieve a larger integer representation.
C language Dynamic memory application and release makes the code error-prone, so you can consider using C + + smart pointers Instead, or define a matrix class to achieve =,* and other matrix operations.
Solving the nth term of the Fibonacci sequence