使用堆栈递归循环

时间:2014-10-15 18:13:12

标签: c++ loops recursion stack

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

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 个答案:

答案 0 :(得分:1)

你的问题是第一次调用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;
  }
}

答案 1 :(得分: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 << " ";
}