我想知道如何(或者甚至可能)在没有调用自身的单独函数的情况下实现递归。 到目前为止,我所见过的所有实现递归的算法都使用了一个单独的函数。我想了很多,并想出一个带有一些变量突变的goto语句可以完成这项工作的想法,但我真的不确定。 我进行了一项小型研究,发现了有关此Structured programming theorem的信息,证明每个算法只能用三种数据结构实现,因此这种递归实现必须是可行的,但我仍然无法将所有内容组合成一致的知识和理解。整个可能的方法。
答案 0 :(得分:2)
您正在寻找的是基本上将递归函数表达为迭代形式。 这可以通过使用堆栈轻松完成。这是C#中一个非常简单的例子:
int NodeCount(Node n)
{
if (n.Visited) return 0; // This node was visited through another node, discard
n.Visited = true;
int res = 1;
foreach (Node ni in n.Children) // Recurse on each node
{
res += NodeCount(ni); // Add the number of sub node for each node
}
return res;
}
以下是迭代形式的完全相同的函数:
int NodeCount(Node root)
{
int res = 0;
Stack<int> stk = new Stack<int>();
stk.Push(root) // We start with the root node
while( stk.Count > 0) // While we still have nodes to visit
{
Node current = stk.Pop(); // Get the node on top of the stack
current.Visited = true; // Mark it as visited
res ++; // Add one to the count
foreach (Node ni in n.Children) // Push all non visited children to the stack
{
if (ni.Visited == false)
stk.Push(ni);
}
}
return res;
}
答案 1 :(得分:1)
在没有调用自身的单独函数的情况下实现递归。
是的,可以将递归算法转换为迭代算法。但是为什么要使用goto
语句?当您进行函数调用时,生成的程序集有一个分支指令,用于与特定函数jumb,其作用类似于goto
。
所以你要完成的有点类似于机器代码最终会做的事情,有利于避免堆栈帧调用以及使用goto
的可怕的spaggeti代码的缺点。
如果要避免递归,请使用迭代。你是怎么想出这个问题的?
答案 2 :(得分:1)
您可以使用任何基于堆栈的语言执行一种没有函数的递归。例如,在Forth中你可以像这样编写斐波纳契函数:
:斐波那契0 1 10 0做2dup +腐烂。循环交换。 。 ;
该程序递归地生成10次斐波那契序列迭代,每次迭代使用前一次迭代的输入。没有调用任何函数。