看数据结构看到Fibonacci,而且说如果用递归的方法来实现的话会很低效,尤其是Index比较大的情况下,遂决定试一下。
代码和输出在下面,观察输出,Index为50的时候,递归时间就已经好久了,再大一点我等不及了。调用次数也是指数级的上升,而与之对比的是,迭代的调用次数和时间始终在一个可控的范围内。有趣的是观察Recurse的调用次数也形成了一个Fibonacci序列的变体,F(N)=F(N-1)+F(N-2)+N-1。
造成递归调用如此低效的原因在于求解F(N)的时候需要算一遍F(N-1)和F(N-2),求解F(N-1)的时候需要算一遍F(N-2)和F(N-3),可以看出F(N-2)在求解相邻的两个值的时候被算了两遍,如此不断垒乘下去,会造成很大的浪费,这也违背了递归调用的第四条原则:“
Compound interest rule
Never duplicate work by solving the same instance of a problem in separate recursive calls.
”</pre><p><pre name="code" class="cpp">//============================================================================
// Name : myAlgorithm.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
#include <time.h>
long iRecurseCalledTimes=0;
long iIterationCalledTimes=0;
long funcRecurse(long n)
{
iRecurseCalledTimes++;
if(2==n||1==n)
return 1;
else
return funcRecurse(n-1)+funcRecurse(n-2);
}
long funcIteration(long n)
{
iIterationCalledTimes++;
long i0=0,i1=1,result=1;
if(2==n||1==n)
return 1;
else
for(long i=2;i!=n+1;i++)
{
result=i0+i1;
i0=i1;
i1=result;
}
return result;
}
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
unsigned long iTestMax=0;
cin>>iTestMax;
clock_t start, finish;
double duration[2];
long lRtn[2];
cout<<"Index\tR-Time\tI-Time\tR-Calls\tI-Calls\tR-Rtn\tI-Rtn\t"<<endl;
for(long i=1;i!=iTestMax+1;++i)
{
start = clock();
lRtn[0]=funcRecurse(i);
finish = clock();
duration[0] = (double)(finish - start) / CLOCKS_PER_SEC;
start = clock();
lRtn[1]=funcIteration(i);
finish = clock();
duration[1] = (double)(finish - start) / CLOCKS_PER_SEC;
cout << i << "\t"<< duration[0] << "\t" << duration[1] << "\t" << iRecurseCalledTimes << "\t" << iIterationCalledTimes << "\t" << lRtn[0] <<"\t" << lRtn[1] <<endl;
}
return 0;
}
!!!Hello World!!!
50
Index R-Time I-Time R-Calls I-Calls R-Rtn I-Rtn
1 0 0 1 1 1 1
2 0 0 2 2 1 1
3 0 0 5 3 2 2
4 0 0 10 4 3 3
5 0 0 19 5 5 5
6 0 0 34 6 8 8
7 0 0 59 7 13 13
8 0 0 100 8 21 21
9 0 0 167 9 34 34
10 0 0 276 10 55 55
11 0 0 453 11 89 89
12 0 0 740 12 144 144
13 0 0 1205 13 233 233
14 0 0 1958 14 377 377
15 0 0 3177 15 610 610
16 0 0 5150 16 987 987
17 0 0 8343 17 1597 1597
18 0 0 13510 18 2584 2584
19 0 0 21871 19 4181 4181
20 0 0 35400 20 6765 6765
21 0 0 57291 21 10946 10946
22 0 0 92712 22 17711 17711
23 0 0 150025 23 28657 28657
24 0 0 242760 24 46368 46368
25 0 0 392809 25 75025 75025
26 0 0 635594 26 121393 121393
27 0 0 1028429 27 196418 196418
28 0 0 1664050 28 317811 317811
29 0 0 2692507 29 514229 514229
30 0.01 0 4356586 30 832040 832040
31 0.01 0 7049123 31 1346269 1346269
32 0.01 0 11405740 32 2178309 2178309
33 0.03 0 18454895 33 3524578 3524578
34 0.04 0 29860668 34 5702887 5702887
35 0.06 0 48315597 35 9227465 9227465
36 0.1 0 78176300 36 14930352 14930352
37 0.17 0 126491933 37 24157817 24157817
38 0.26 0 204668270 38 39088169 39088169
39 0.44 0 331160241 39 63245986 63245986
40 0.71 0 535828550 40 102334155 102334155
41 1.14 0 866988831 41 165580141 165580141
42 1.89 0 1402817422 42 267914296 267914296
43 2.97 0 2269806295 43 433494437 433494437
44 4.79 0 3672623760 44 701408733 701408733
45 7.78 0 5942430099 45 1134903170 1134903170
46 12.66 0 9615053904 46 1836311903 1836311903
47 20.61 0 15557484049 47 2971215073 2971215073
48 33.24 0 25172538000 48 4807526976 4807526976
49 53.99 0 40730022097 49 7778742049 7778742049
50 88.66 0 65902560146 50 12586269025 12586269025