有一些遞歸算法可以很快填滿堆棧。一種解決方法是使棧顯式化,從而將算法轉換爲迭代算法。使顯式堆棧算法更快
但我注意到有了顯式堆棧會讓算法慢得多(這可能不會讓我感到意外)。是否有任何通用的C++指南可以更快地製作顯式堆棧?它們可能比原始遞歸算法運行得更快嗎?
編輯:我寫了一個明確的堆棧功能如下。我也粘貼了迭代代碼。出於某種原因,使用std::vector
而不是std::stack
會更快,這是相當令人驚訝的。
// A(m, n) = n + 1 if m = 0
// = A(m - 1, 1) if m > 0 and n = 0
// = A(m - 1, A(m, n - 1)) if m, n > 0
int A(int m, int n, long& iterations,
std::vector<std::pair<int, int> >& stack)
{
stack.push_back(std::make_pair(m, n));
long result = 0;
bool result_available = false;
while (stack.size() > 0)
{
iterations += 1;
if (result_available) {
stack.back().second = result;
result_available = false;
}
m = stack.back().first;
n = stack.back().second;
stack.pop_back();
if (m == 0) {
result = n + 1;
result_available = true;
}
else if (m > 0 && n == 0) {
stack.push_back(std::make_pair(m - 1, 1));
}
else if (m > 0 && n > 0) {
stack.push_back(std::make_pair(m - 1, n));
stack.push_back(std::make_pair(m, n - 1));
}
}
return result;
}
如果你包括一個遞歸和顯式堆棧版本的算法,其中時間顯着不同,這將更容易回答。一般來說,很難回答性能問題(超越算法複雜性),因爲影響性能的因素很多。 – Mankarse
嚴格猜測(正如@Mankarse所說,顯示一些代碼),但是創建堆棧幀通常比分配堆內存要快得多,所以如果迭代方法最終頻繁地擴展堆棧,您將會受到堆分配的影響。解決方案是使分配更少頻繁... –
某些類型的遞歸可以被消除到一個循環(尾遞歸)。那麼你根本不需要堆棧。知道實際的算法和遞歸行爲是很好的。 –