1. 循环的效率高于递归
相比较循环,递归的代码非常简洁。递归是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。所以不难理解递归的实现效率不如循环。
此外,递归中有可能很多计算都是重复的,从而对性能带来很大的负面影响。递归的本质是把一个问题分解成两个或者多个问题。如果多个问题存在相互重叠的部分,那么就存在重复计算。
除了运行效率之外,递归还有可能引起更加严重的问题:调用栈溢出。因为每一个进程的栈容量都是有限度的。当递归调用的层级太多的时候,就会超出栈的容量,从而导致调用栈溢出。
2. 程序分析:斐波那契序列
// 递归解法 long long Fibonacci(unsigned int n) { if( n <= 0 ) return 0; if( n == 1 ) return 1; return Fibonacci(n-1)+Fibonacci(n-2); }
上面的解法其实具有很严重的效率问题。
这棵树中有很多节点都是重复的,而且重复的节点数会随着n的增大而急剧增加(事实上,用递归方法计算的时间复杂度是以n的指数的方式递增的)。如果n=100,计算的复杂度会相当的大。
更实用的方法应该调用循环(时间复杂度为n),如下:
long long Fibonacci(unsigned int n) { int res[2] = {0,1}; if (n<2) return res[n]; long long One = 1; long long Two = 0; long long fibN = 0; for(unsigned int i = 2; i <= n, i++) { fibN = One+Two; Two = One; One = fibN; } return fibN; }