循环与递归

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);
}

上面的解法其实具有很严重的效率问题。

循环与递归_第1张图片

这棵树中有很多节点都是重复的,而且重复的节点数会随着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;
}


你可能感兴趣的:(数据结构与算法导论)