递归的本质(Essential of Recursive)

最初让我体会递归的就Joe的《Programming Erlang》,随着对计算(computing)的理解,对递归的体会也会有所不同。这里我记录下我的理解过程。

1,理解递归

递归是需要List这种结构的,这也是为什么Lisp本身就是LISt Processor表缩写。数据是表,那么我们可以一个个地处理表中的每个元素。处理方式也颇为简单:

1,解决空表的特殊情况。

2,处理头元素,一般是一个S-expressions(atom or list)。

3,递归处理尾元素。尾元素通常表示为:(cdr lst)。

 

上面这句话还可以再简练些:

1,擦屁股

2,处理头

3,递归尾

 

2,递归解构

能达到什么样要求的语言才可以实现递归?

很明显,递归的函数必须接受List作为其参数(arguments),所以必须有类型List这样的数据结构。其次,必须有first, rest这样的no effect side数据返回提取操作。

我们来说说函数,其实函数是具名的Processor,除此之外他还表示高一层的抽象——他是一个处理过程。当一个函数(处理过程)接受List类型时,这个函数离“可递归”不远了。

 

3,解决问题的递归

记得刚学面向对象时,当某些人说:“一功都是对象”。就会觉得某人牛逼,顿时崇拜有加。但随着时间的深入,有些觉得挺扯蛋的。比如在一些控制操作比较多的应用中,如果你用OOP的话,那些你创建了一堆臆想的对象。这不就是为OOP而OOP嘛。

推理到这里,递归也不适合解决所有问题。但确实有些问题从本质上就是递归的,比如快速排序,用Erlang来表示的话就是:

sort([Pivot|T]) ->
    sort([ X || X <- T, X < Pivot]) ++
    [Pivot] ++
    sort([ X || X <- T, X >= Pivot]);
sort([]) –> [].

从完成任务的思想上来说:

1,擦屁股(当list为空时直接返回空)。

2,处理头(Pivot)。

3,递归尾(T < Pivot和T >= Pivot)。其实这里更通俗的说法是处理剩下的,也就是比Pivot大的比Pivot小的

如果用自然语言来说比较绕,也就是把第1个元素当Pivot,然后将比Pivot小的放到Pivot前面,将比Pivot大的放到Pivot后面。怎么知道是否比Pivot大?递归回去直到只有一个元素。

 

我这里说这么多无非就是递归只是一种抽象方式,也是看世界的一个角度。有时候从这个角度看世界很清晰,有时候根本看不清。可以尝试从另一个角度观察,尽量贴近问题域来解决问题,而不是解决方案域来解决问题。

转载于:https://www.cnblogs.com/Jerry-Chou/archive/2012/03/13/2394198.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值