我给了这样一棵树:

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;迭代。结果 我该如何解决这个问题?

有帮助吗?

解决方案

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

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

其他提示

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

//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循环,许多编译器甚至会为你做这个。

一些更加数学化的递归调用可以通过重复关系来解决。您遇到这些尚未解决的可能性不大可能,但您可能会感兴趣。

//编辑,表现? 真的取决于您的实现和树的大小。如果你的递归调用有很多深度,那么你将获得堆栈溢出,而迭代版本将表现良好。我会更好地掌握递归(如何使用内存),你应该能够决定哪种更适合你的情况。 以下是使用斐波那契数字进行此类分析的示例

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

以下是关于此主题的 Phil Haack的文章

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top