使用堆栈循环的递归

Recursion to loop using a stack

本文关键字:递归 循环 堆栈      更新时间:2023-10-16

我想使用堆栈和循环将以下程序转换为非递归代码:

void write(int n) {
    if (n>0) {
        write(n-1);
        cout << n << " ";
        write(n-1);
    }
}

这是我正在使用的代码,但目前不起作用,我不知道为什么:

stack<int> S;
S.push(n);
while (not S.empty()) {
    int k = S.top(); 
    S.pop()
    if (k>0) {
        S.push(k-1);
        cout<<k<<" ";
        S.push(k-1);
    }
}

它不起作用,我不知道如何模拟递归。我认为将等效的递归调用推入堆栈就足够了。

感谢

问题是对堆栈进行2次推送,但在打印之前会递归调用第一个write(),并使用所有调用链。

以下是递归调用的迭代等价物:

std::stack<int> S;
for( int i = n; i > 0; --i )
   S.push( i );
while( not S.empty() ) {
    int k = S.top();
    S.pop();
    for( int i = k - 1; i > 0; --i ) {
        S.push( i );
    }
    std::cout << k << " ";
}

您的问题是,对write(n - 1)的第一次调用发生在输出之前,但对弹出值的评估发生在输出之后。

你可以让你的堆栈模拟实际的激活记录:

enum Action
{
  Call, Write
};
struct Record
{
  Action action;
  int arg;
};
stack<Record> S;
S.push({Call, n});
while (not S.empty()) {
  auto rec = S.top();
  S.pop()
  switch (rec.action) {
    case Call:
      if (rec.arg > 0) {
        S.push({Call, rec.arg - 1}); // corresponds to 2nd write() call
        S.push({Write, rec.arg});
        S.push({Call, rec.arg - 1}); // corresponds to 1st write() call
      }
      break;
    case Write:
      std::cout << rec.arg << ' ';
      break;
  }
}