【发布时间】:2010-11-04 16:47:56
【问题描述】:
是否有一种算法可以将高度递归的函数优化为对数据结构的迭代?例如,给定以下函数...
// template <typename T> class BSTNode is defined somewhere else
// It's a generic binary search tree.
template <typename T, typename R>
void in_order(BSTNode<T>* root, R (*routine)(T))
{
if (root)
{
in_order(root->leftChild);
routine(root->data);
in_order(root->rightChild);
}
}
...可以优化成...
// template <typename> class Stack is defined somewhere else
// It's a generic LIFO array (aka stack).
template <typename T, typename R>
void in_order(BSTNode<T>* root, R (*routine)(T))
{
if (!root) return;
Stack<BSTNode*> stack;
stack.push(NULL);
line1:
while (root->leftChild)
{
stack.push(root);
root = root->leftChild;
}
line2:
routine(root->data);
if (root->rightChild)
{
root = root->rightChild;
goto line1;
}
else if (root = stack.pop())
goto line2;
}
(当然不同的是,调用栈不是填充调用栈,而是填充堆中的另一个栈。)
编辑:我的意思是可以由编译器执行的算法,所以我不必手动优化它。
【问题讨论】:
-
当您问“是否有算法”时,您是在问是否有人类可以遵循的通用算法来执行转换,或者您是否在问是否有一些 STL 或其他功能要做这是自动的吗?
-
一种可由任何语言的编译器执行的算法,不一定是 C++ 编译器。
-
这不会是对大多数 CPU 架构和语言的优化,因为基于处理器的调用堆栈比您使用的自定义构建堆栈快得多(因为它是处理器内部的)在你的第二个例子中。您应该使用迭代的较短的递归变体,因为它可能更快且更易于阅读。如果可能有更快的实现,那么现在大多数编译器已经在一定程度上展开了这样的循环。您应该在这里依赖编译器本身。如果有疑问,请使用第一条优化规则:衡量。
-
如果“任何语言”是你想要的,这里是 LISP 的一个:user.it.uu.se/~torer/publ/remrec.html——这里是 PL/I 的一个:portal.acm.org/citation.cfm?id=359344——这是一个长期存在的、仍然活跃的领域研究,但我不知道有任何流行语言的编译器实际上提供了此类工具。
标签: optimization data-structures recursion