是否可以使用迭代器实现递归算法?

时间:2009-07-29 16:42:18

标签: c++ algorithm computer-science

我给了这样一棵树:

http://www.seqan.de/dddoc/html/streePreorder.png http://www.seqan.de/dddoc/html/streePreorder.png

我可以使用下一个运算符访问每个节点。

// postorder dfs
Iterator< Index<String<char> >, BottomUp<> >::Type myIterator(myIndex);
for (; !atEnd(myIterator); goNext(myIterator)) 
    // do something with myIterator

但我想在树上使用递归算法 有没有办法可以使递归算法(在每个节点上排除最大的子树)迭代? 或者我如何非递归地访问元素?

修改: 实际问题:
我给出了一个递归算法,适用于树。 (递归)
我还使用了一个库,我只能用迭代器访问Items(非标准,迭代)

递归&lt; - &gt;迭代。
我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

您可以借助堆栈将那个递归函数转换为迭代函数。

//breadth first traversal pseudo-code
push root to a stack
while( stack isn't empty )
    pop element off stack
    push children
    perform action on current node

取决于您想要遍历节点的方式,实现方式会有所不同。所有递归函数都可以转换为迭代函数。关于如何获取特定问题的信息的一般用法。使用堆栈/队列并转换为for循环是应该解决大多数情况的常用方法。

你还应该研究尾递归以及如何识别它们,因为这些问题很好地转化为for循环,许多编译器甚至会为你做这个。

recurrence relations可以解决一些更加数学化的递归调用。您遇到这些尚未解决的可能性不大可能,但您可能会感兴趣。

//编辑,表现? 真的取决于您的实现和树的大小。如果你的递归调用有很多深度,那么你将获得堆栈溢出,而迭代版本将表现良好。我会更好地掌握递归(如何使用内存),你应该能够决定哪种更适合你的情况。 Here is an example of this type of analysis with the fibonacci numbers

答案 1 :(得分:1)

任何递归函数也可以使用堆栈实现。如果这是你要问的问题。

这是关于这个主题的article by Phil Haack

性能增益的一种方式或另一种方式是推测性的,编译器使用我们在幕后无法始终预测的代码来完成任务。实现两者并得到一些实数。如果它们相似,请使用您认为更具可读性的那个。

答案 2 :(得分:1)

如果您的迭代器仅支持向前(可能是向后)遍历,但不支持树上的链接或快速随机访问,那么您将很难适应树算法。但是,最后任何答案都将取决于您未提供的自定义迭代器提供的界面。

例如,考虑树搜索的简单算法。如果迭代器给出的唯一操作是“从第一个元素开始并逐个移动”,那么显然无法有效地实现树搜索。你也不能实现二进制搜索。因此,您必须提供确切支持哪些操作的列表,以及(严格地说)每个操作的复杂性限制。

答案 3 :(得分:0)

即使使用递归迭代,您最终也会获得每节点节点访问。

你需要知道的是:我的迭代器如何被告知深度优先,然后:我将如何通知一个级别已经开始/结束(即递归步骤的开始/结束)。 / p>

这些知识可以映射到递归算法上。