关于算法中递归与迭代的小感想

        最近刚看完SICP第一章,有一些想法,记录下来。

      以斐波那契数为例,它的规则是以0、1为前两个数,从第三个数开始,Fib(n)为前两个数之和。

      如果要将上述算法进行语言描述,最简单的莫过于递归了。

       int Fib(int n)

    { 

            if (n==0)  Fib(n)=0;

            else if (n==1) Fib(n)=1;

            else Fib(n)=Fib(n-1)+Fib(n-2);

            return 0;

    }

       仔细观察,会发现,递归的算法只不过是将问题本身描述了一遍,几乎不用怎么动脑子的。我们用问题本身去解决问题,很神奇,但也很令人不安。

        我们只描述了当前一步的情况,把推后要进行的工作统统扔给计算机了,好在每一步的工作都一样。计算机所要做的就是重复的构造出下一步、下下一步直到终于遇见一个具体的数,也就是n=0的时候,它发现到头了,该计算了。然后再从头算起直到n=n。

         可以看到实际计算之前,计算机首先要将推后k步所要干的事情描述出来。怎么描述,当然是把它存起来,存到堆栈里去。但是如果这个n是个极大的数的时候,大到超过内存的容量,那么我们这个问题就无法实现了。

         是的,递归算法如此容易理解,同时,也存在一个致命的缺陷,就是太占内存。

         聪明的我们这个时候就应该想一个办法,如何去克服它的缺陷,如何优化。

         回顾一下,递归是从n开始思考的。

         而你,遇到这个问题,你是怎么解决的呢?

         一般都是从零开始,一个一个的加。我们不会和计算机一样傻,要先把所有要做的东西列出来。是的,太累赘了。但我们做加法的速度太慢,所以让我们把这些烦人的加法甩给计算机吧。它不会抱怨,哪怕是一直重复。

         int Fib(int n)

        {

              int a=0,b=1;

              for(int i=0;i<n-1;i++)

                 {

                    a=b;

                    b=a+b;

                 }

                return 0;

          }

        前人将上述考虑问题的方法定义为迭代。

        我的理解是,构造出变量,染后按照一个规则不断更新变量的值。直到它们变为我们想要的值。

         上述问题用迭代只需要分配三个字长的内存空间,a、b、n。我们解决了递归问题中耗费内存的问题。

         而转折点是,我们洞察了我们是如何思考的,计算机会傻傻地一直构造出一个长堆栈,但我们不会。

          《代码大全》里有一句话,“如果我的程序员用递归去求阶乘,我宁愿炒掉他。”

 递归对于计算机来说实在是费力不讨好的事情,又占内存,又浪费时间。但是它无疑是我们人脑抽象问题的第一步,最简单的思维模式。

           当我们想要解决一个问题的时候,不妨先用递归去思考,然后画出递归树;接下来一定可以发现我们重复了很多操作,比如这里计算Fib(4)的时候要用到Fib(3)的值,而Fib(3)在我们的上一步已经计算过了。所以我们可以用一个变量来存放我们每一步所得到的值,以供下一步所用。逐步地这样去思考,我们就将一个递归的问题变成了迭代。这便体现出计算机里很重要的一个思想,“以空间换时间”。如果你还可以发现迭代问题里的一些废操作,并想方设法将其解决,程序的性能会进一步提高,算法的重要性亦在于此。

            








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值