答案 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)
是的,每个递归函数都可以转换为迭代函数。