递归函数被转换为非递归函数

时间:2011-02-15 11:18:30

标签: algorithm optimization recursion

  

可能重复:
  Can every recursion be converted into iteration?

是否可以将递归函数转换为非递归函数或非递归函数集?

你能指出一些有用的例子吗?

由于

5 个答案:

答案 0 :(得分:7)

这总是可行的,因为您可以自己模拟调用堆栈。但是,这并不总是那么容易。

简单的情况是尾递归:这些甚至不需要堆栈。例如,这个人很容易转换成for循环:

def countdown(n):
    if n >= 0:
        print n
        countdown(n-1)

即使函数不是严格的尾递归,有时你仍然可以在没有堆栈的情况下逃脱。例如,经典因子函数:

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

当有多个递归调用时会变得更难。例如,考虑一下快速排序:

def quicksort(array):
    if len(array) <= 1:
        return array
    else:
        pivot = array[0]
        left = quicksort([x for x in array[1:] if x < pivot])
        right = quicksort([x for x in array[1:] if x >= pivot])
        return left + [pivot] + right

虽然绝对有可能在没有递归的情况下执行此操作,但您必须自己构建一个堆栈,并构造一个迭代的while循环,直到堆栈为空。

答案 1 :(得分:4)

是的,总是可以将递归函数转换为非递归函数。

你可以用简单的思想实验证明这一点:你可以实现一个简单的非递归解释器,它模拟一个带有堆栈的图灵完备寄存器机器(基本上相当于一个简单的微处理器)。这是一个非递归代码,可以运行任何递归函数。

请注意,在所有非平凡的递归情况下(即比简单的尾递归更复杂,只能转换为循环),您需要以某种方式捕获嵌套堆栈帧中包含的信息。通常,这可以通过使用堆内存模拟可变大小的堆栈来完成,但也可以使用其他技术(例如,continuation或队列)。

答案 2 :(得分:2)

始终可以使用stack将递归转换为迭代。您可以在堆栈上推送参数集,而不是使用某些参数进行递归调用。在每次迭代中,弹出并处理顶部参数集。

答案 3 :(得分:1)

所有递归函数都可以转换为迭代函数,但不是那么简单。

尾递归的情况下,这很简单。这是只发生一次递归调用并在最后发生的情况。这可以简单地转换为do-while语句。

对于其他情况,并非如此简单。虽然所有递归都可以转换为迭代,但您需要在更复杂的示例中模拟自己的堆栈。

答案 4 :(得分:0)

是的,每个递归函数都可以转换为迭代函数。