递归与迭代

      递归函数在运行时将带来一部分运行时开销:参数必须压栈、为局部变量分配内存、寄存器的值必须保存等;当递归函数每次调用返回时,上述的操作都需要还原恢复成原来的样子。因此递归函数的效率并不会很高;

      一个递归的函数往往可以改写成迭代的形式,而迭代比递归的效率要高很多,许多问题以递归的方式进行描述并不是因为这种问题适合使用递归的方式来解决,而是因为使用递归描述更简洁直观,这些问题的迭代实现往往比递归要好的多,虽然代码的可读性要差一点儿,但是当一个问题相当复杂时,递归的简洁性可以弥补它的运行时开销。

     这里有一个比较极端的例子,斐波那契数列,它常常以递归的形式进行描述:当n <= 1 时,Fibonacci(n) = 1;当 n = 2 时,Fibonacci(n) = 1;当n > 2 时,Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2);

    这种描述方式很容易诱导人们使用递归函数来解决问题:

 

     long Fibonacci( int n )

     {

          if( n <= 2 )

          {

               return 1;

          }

 

          return ( Fibonacci(n-1) + Fibonacci(n-2) );

     }

 

 分析一下最后一跳语句,在计算Fibonacci(n-1)时,将计算一次Fibonacci(n-2),但是在后面又有一次计算Fibonacci(n-2)的值的情况,这将会造成一次冗余计算,然而实际情况却比这个要糟糕的多,每一个递归调用到会触发另外两个递归调用,而这两个递归调用中的任何一个又都会触发两个递归调用,这样冗余计算的数量将增长的非常快。例如在执行Fibonacci(10)时,Fibonacci(3)将会被执行21次,但是递归计算Fibonacci(30)时,Fibonacci(3)将会被计算30多万次(可以使用一个静态变量来计算Fibonacci(3) 的执行次数)!!当这30多万次的计算结果都是一样的,处了其中一个是必须的其他的都属于浪费。

 

    现在如果使用迭代来解决这个问题,程序的效率提高将是巨大的,尤其是n的值相当大的时候:

 

    long Fibonacci( int n )

    {

         long result;

         long previous_result;

         long next_older_result;

         result = previous_result = 1;

         while ( n > 2 )

         {

              n -= 1;

              next_older_result = previous_result;

              previous_result = result;

              result = next_older_result + previous_result;

         } 

 

         return result;

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值