所有的迭代algorithm都可以recursion表示吗?

如果没有,是否有一个很好的反例,显示一个迭代algorithm,其中不存在recursion对应?

如果所有迭代algorithm都可以recursion表示,那么这种情况是否更难?

另外,编程语言在这一切中扮演着什么angular色? 我可以想象,Scheme程序员对于迭代(=尾recursion)和堆栈使用有不同的看法,而不是只用Java的程序员。

有一个简单的特别certificate。 由于您可以使用严格的迭代结构和仅使用recursion结构的Turn完成语言来构build图灵完备语言,因此这两者是等效的。

所有的迭代algorithm都可以recursion表示吗?

是的,但证据不是很有意思:

  1. 将所有控制stream程转化为一个包含单个case语句的单个循环,其中每个分支是直线控制stream,可能包括breakreturnexitraise等。 引入一个新的variables(称之为“程序计数器”),case语句用来决定下一个要执行的程序段。

    这种构造是在20世纪60年代的大规模“结构化编程之战”中被发现的,当时人们正在争论各种控制stream构造的相对performance力。

  2. 将循环replace为recursion函数,并将每个可变局部variablesreplace为该函数的参数。 瞧! recursion取代迭代。

这个过程相当于为原始函数写一个解释器。 正如你可能想象的那样,它会导致代码不可读,而且这不是一件有趣的事情。 然而 ,一些技术对于有命令式编程背景的人来说是有用的,他们正在学习第一次以function语言进行编程。

就像你说的,每一个迭代的方法都可以变成一个“recursion”的方式,而且在尾部调用的时候,栈也不会爆炸。 事实上,这实际上是Scheme如何实现所有常见的循环forms。 scheme中的示例:

 (define (fib n) (do ((x 0 y) (y 1 (+ xy)) (i 1 (+ i 1))) ((> in) x))) 

在这里,虽然函数看起来是迭代的,但它实际上是在一个内部的lambda函数上recursion,它接受三个参数xyi ,并在每次迭代时调用新的值。

以下是一种可以扩展function的方法:

 (define (fib n) (letrec ((inner (lambda (xyi) (if (> in) x (inner y (+ xy) (+ i 1)))))) (inner 0 1 1))) 

这样,recursion性变得更加直观。

定义迭代为:

 function q(vars): while X: do Y 

可以翻译为:

  function q(vars): if X: do Y call q(vars) 

在大多数情况下,Y会包括增加一个由Xtesting的计数器。这个variables在进行recursion路由时必须以某种方式传递给“variables”。

正如在他们的答案中指出的那样,我们可以构造certificaterecursion和迭代是等价的并且可以用来解决同一个问题的certificate。 然而,尽pipe我们知道这两者是相同的,但使用这两者却有缺点。

在未针对recursion进行优化的语言中,您可能会发现使用迭代的algorithm比recursion的algorithm执行得更快,甚至在优化的语言中,您也可能发现使用不同语言编写的迭代的algorithm比recursion更快。 此外,使用recursion与迭代编写给定的algorithm可能没有明显的方式,反之亦然。 这可能会导致难以阅读的代码,从而导致可维护性问题。

Prolog是recursion唯一的语言,你可以做几乎所有的东西(我不build议你这样做,但你可以:))

与迭代解决scheme相比, recursion解决scheme通常效率较低 。 然而,注意到有一些问题只能通过recursion来解决,并且等价的迭代解决scheme可能不存在或者非常复杂,以至于不容易编程(例如,阿克曼函数不能在没有recursion的情况下被expression)。尽piperecursion是优雅的,写和理解。