使用堆栈循环的递归
Recursion to loop using a 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次推送,但在打印之前会递归调用第一个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;
}
}
相关文章:
- 为什么在递归中使用循环会产生意想不到的结果?
- 无穷大而循环时具有递归函数
- 如何使用递归循环我的代码(当用户输入无效输入时,它会再次提示他们)?
- C++ 模板使用递归实现循环
- C++ 使用递归而不是 for 循环
- 递归应用 C++20 范围适配器会导致编译时无限循环
- 为什么这个递归函数会创建一个无限循环?
- 如何使用循环编写此递归
- 计算递归和时的无限循环
- 递归回溯打印长度为N的二进制数的所有组合,而不使用循环
- 递归导致程序崩溃,但 while 循环中的相同概念不是来自C++析构函数
- C++ 循环链表的递归基本情况
- 循环访问多个模板参数的递归模板函数
- 在 C++ 中用递归替换循环的 N 级
- 如果找不到解决方案,我如何留下递归循环,而不会打印任何东西
- 如何在C++中将基本嵌套循环转换为递归循环
- 在递归循环中条件修改的引用内存
- 递增迭代器并在递归循环中传递参数
- 当在有限递归循环中操作大型数组时,我应该在哪一点从堆栈切换到堆?
- 递归循环(c#)