Pet*_*son 1 language-agnostic recursion
我听说任何递归算法都可以通过堆栈来表达.最近,我一直致力于在可用调用堆栈大小过小的环境中开发程序.
我需要做一些深度递归,所以我想知道如何重写任何递归算法以使用显式堆栈.
例如,假设我有一个像这样的递归函数
function f(n, i) {
if n <= i return n
if n % i = 0 return f(n / i, i)
return f(n, i + 1)
}
Run Code Online (Sandbox Code Playgroud)
我怎么能用堆栈来代替呢?是否有一个简单的过程可以将任何递归函数转换为基于堆栈的函数?
如果您了解函数调用如何影响进程堆栈,您可以自己了解如何执行此操作.
调用函数时,会在堆栈中写入一些数据,包括参数.该函数读取这些参数,对它们执行任何操作并将结果放在堆栈上.你可以做同样的事情.你的例子特别不需要堆栈,所以如果我将它转换为使用堆栈的那个,它可能看起来有点傻,所以我将给你斐波那契的例子:
fib(n)
if n < 2 return n
return fib(n-1) + fib(n-2)
function fib(n, i)
stack.empty()
stack.push(<is_arg, n>)
while (!stack.size() > 2 || stack.top().is_arg)
<isarg, argn> = stack.pop()
if (isarg)
if (argn < 2)
stack.push(<is_result, argn>)
else
stack.push(<is_arg, argn-1>)
stack.push(<is_arg, argn-2>)
else
<isarg_prev, argn_prev> = stack.pop()
if (isarg_prev)
stack.push(<is_result, argn>)
stack.push(<is_arg, argn_prev>)
else
stack.push(<is_result, argn+argn_prev>)
return stack.top().argn
Run Code Online (Sandbox Code Playgroud)
说明:每次从堆栈中获取项目时,都需要检查是否需要扩展它.如果是这样,在堆栈上推送适当的参数,如果没有,让它与之前的结果合并.在fibonacci的情况下,一旦fib(n-2)被计算(并且在堆栈顶部可用),n-1则检索(在堆栈顶部之后),fib(n-2)在其下推送结果,然后fib(n-1)展开并计算.如果堆栈的前两个元素都是结果,当然,您只需添加它们并推送到堆栈.
如果你想看看你自己的功能是什么样的,这里是:
function f(n, i)
stack.empty()
stack.push(n)
stack.push(i)
while (!stack.is_empty())
argi = stack.pop()
argn = stack.pop()
if argn <= argi
result = argn
else if n % i = 0
stack.push(n / i)
stack.push(i)
else
stack.push(n)
stack.push(i + 1)
return result
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1957 次 |
| 最近记录: |