• SICP 关于递归迭代的重新理解以及尾递归的引入...



    看了线性的递归和迭代以及树形递归迭代这部分的内容,感觉对递归和迭代又有了新的理解...所以记录一下,也算对这部分内容的总结吧.

    首先书中提到的递归与迭代和我以前想的有点不一样,我感觉书中提到的递归和迭代是站在编译器/解释器的基础上来看的,而我之前是站在语言(类C语言的)的具体实现的角度看的.
    理解这个需要先看书中提到的两个概念:

                       1.递归过程
                       2.递归的计算过程

    可以用书中举出的阶乘的例子来看

    实现1:

    1 (factorial 6)
    2 (* 6 (factorial 5))
    3 (* 6 (* 5 (factorial 4)))
    4 (* 6 (* 5 (* 4 (factorial 3))))
    5 ...
    6 (* 6 (* 5 (* 4 (* 3 (*2 (factorial 1)))))) ---> 720


    实现2:

    1 (factorial 6)
    2 (fact-iter 1 1 6)
    3 (fact-iter 1 2 6)
    4 (fact-iter 2 3 6)
    5 (fact-iter 6 4 6)
    6 (fact-iter 24 5 6)
    7 (fact-iter 120 6 6)
    8 (fact-iter 720 7 6) ---> 720


    实现1就是递归的计算过程, 实现2是迭代的计算过程.区别在于:从编译器的角度看, 实现1的实现需要系统维护以后将要执行操作的轨迹,随着递归深度的加深,所需要保存的信息量线性增长. 而对于实现2, 其状态可以用固定数量的状态变量进行描述.
    换句话讲,在实现2中,过程中的任何一个点都提供了关于计算状态的完整描述.

    1          c --> 递归计算过程
    2 递归过程{           --> 迭代计算过程
    3          scheme {
    4                    --> 递归计算过程


    然而这两种实现从语言实现的角度来看(c), 都可以用递归实现, 也就都可以称做是递归过程. 然而c语言编译器这种对于递归的这种解释不论是空间效率和还是时间效率都是不尽人意的(在c语言的实现设计中,对于任何递归的解释都属于递归计算过程即使他们从原理上讲是迭代的),这也是为什么c语言有do...while/for 之类的循环结构的原因(对于scheme则不存在这个设计缺陷 --> scheme解释器采用了尾递归的技巧).


  • 相关阅读:
    Netty入门
    hashCode方法里为什么选择数字31作为生成hashCode值的乘数
    【转】String hashCode 方法为什么选择数字31作为乘子
    NppFTP小插件的使用
    事务的基础入门
    Code Review 程序员的寄望与哀伤【转载】
    谈谈敏捷开发【转载】
    如何写代码 — 编程内功心法【转载】
    面经【转载】
    Swagger的简单入门【转载】
  • 原文地址:https://www.cnblogs.com/nzhl/p/5450376.html
Copyright © 2020-2023  润新知