递归和迭代

SICP中递归和迭代的一点笔记

首先看两个lisp函数,都是用来求阶乘的.

(define (factorial n)
    (if (= n 1)
        1
        (* n (factorial (- n 1)))))
(define (factorial n)
    (fact-iter 1 1 n))
(define (fact-iter product counter max-count)
    (if (> counter max-count)
        product
        (fac-iter (* product counter)
                    (+ counter 1)
                    max-count)))

这两个函数实现的功能是一样的,算法也是一样的.但是计算过程却是不同的.

  • 递归调用过程

递归调用过程

  • 迭代调用过程

迭代调用过程

这两张图是直接从SICP书中抄过来的.

计算过程分类
第一个过程在执行的过程中,解释器要维护操作轨迹,也就是要保存信息.信息量的长度随n的值线性增长.这样的过程称为线性递归过程.

第二个过程可以使用固定数目的变量描述过程.计算步骤随着n线性增长.这种过程称为线性迭代过程.

递归计算过程和递归
只要满足函数调用本身就是递归.以上两个函数都是递归.
但是只有信息量随着调用过程变化的才叫做递归计算过程.
比如第一个函数就是一个递归,同时有着递归计算过程
而第二个函数也是一个递归,但却是迭代计算过程.

C语言中的递归和迭代
在C语言中,无论计算过程从原理上看是递归计算过程还是迭代计算过程,消耗的存储量与调用过程成正比.
因为C语言函数调用是使用栈实现的,为了保护现场,存储返回地址,只要函数自己调用了自己,就是递归计算过程的开销.
为了实现迭代必须使用while,for之类的循环结构.
这是这类语言的弊端.

以上的结论忽略了编译器的作用,现代的编译器一般都会优化递归过程达到尾递归的目的来减小开销.

而scheme中,迭代计算过程是可以在常量空间实现,即使表面上函数自己调用了自己.这一特性也被称为尾递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值