理解递归

转载链接:http://blog.csdn.net/vagrxie/article/details/8470798

理解递归

在初学递归的时候, 看到一个递归实现, 我们总是难免陷入不停的回溯验证之中, 因为回溯就像反过来思考迭代, 这是我们习惯的思维方式, 但是实际上递归不需要这样来验证. 比如, 另外一个常见的例子是阶乘的计算. 阶乘的定义: “一个正整数的阶乘(英语:factorial)是所有小于或等于该数的正整数的积,并且0的阶乘为1。” 以下是Ruby的实现:

def factorial(n) 
  if n <= 1 then
    return 1
  else
    return n * factorial(n - 1)
  end
end

我们怎么判断这个阶乘的递归计算是否是正确的呢? 先别说测试, 我说我们读代码的时候怎么判断呢?
回溯的思考方式是这么验证的, 比如当n = 4时, 那么factoria(4)等于4 * factoria(3), 而factoria(3)等于3 * factoria(2)factoria(2)等于2 * factoria(1), 等于2 * 1, 所以factoria(4)等于4 * 3 * 2 * 1. 这个结果正好等于阶乘4的迭代定义.
用回溯的方式思考虽然可以验证当n = 某个较小数值是否正确, 但是其实无益于理解.
Paul Graham提到一种方法, 给我很大启发, 该方法如下:

  1. 当n=0, 1的时候, 结果正确.
  2. 假设函数对于n是正确的, 函数对n+1结果也正确.    (假设函数对于n-1是正确的, 函数对n结果也正确. 
    如果这两点是成立的,我们知道这个函数对于所有可能的n都是正确的。
对于2,我的理解是就是假设前n-1或n已经是正确的或者说是完成要求的了,现在着手对n或n-1进行操作

这种方法很像数学归纳法, 也是递归正确的思考方式, 事实上, 阶乘的递归表达方式就是1!=1,n!=(n-1)!×n(见wiki). 当程序实现符合算法描述的时候, 程序自然对了, 假如还不对, 那是算法本身错了…… 相对来说, n,n+1的情况为通用情况, 虽然比较复杂, 但是还能理解, 最重要的, 也是最容易被新手忽略的问题在于第1点, 也就是基本用例(base case)要对. 比如, 上例中, 我们去掉if n <= 1的判断后, 代码会进入死循环, 永远不会结束.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值