了解使用堆栈实现队列的递归调用机制
Understanding the recursive call mechanism for implementing a queue using a stack
我正在尝试使用堆栈和递归调用实现队列,这是类堆栈和一些方法:
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
class Node{
public:
int data;
Node* next;
};
Node* top = NULL;
void push(int data){
Node* node = new Node();
node->data = data;
node->next = top;
top = node;
cout << "pushato: " << node->data << "n";
};
bool isempty(){
if(top==NULL){
return true;
}else{
return false;
}
};
void pop(){
if(isempty()){
cout << "lo stack e vuoto.n";
}else{
Node* ptr = top;
top = top->next;
cout << "eliminato: " << ptr->data << "n";
delete(ptr);
}
};
Node* showtop(){
if(!isempty()){
cout << "l'elemento del top e: " << top->data << "n";
return top;
}else{
cout << "lo stack e vuoto.n";
}
};
这是队列的结构:
struct Queue{
void enQueue(int x)
{
push(x);
}
int deQueue()
{
if (isempty()) {
cout << "Q is empty";
exit(0);
}
// pop an item from the stack
int x = showtop()->data;
pop();
// if stack becomes empty, return
// the popped item
if (isempty()){
return x;
}
// recursive call
int item = deQueue();
// push popped item back to the stack
push(x);
// return the result of deQueue() call
return item;
}
};
这是主要的:
int main(int argc, char** argv) {
Queue q;
q.enQueue(1);
q.enQueue(2);
q.enQueue(3);
cout << q.deQueue() << 'n';
cout << q.deQueue() << 'n';
cout << q.deQueue() << 'n';
return 0;
}
这是输出:
pushed:1
pushed:2
pushed:3
popped 3
popped 2
popped 1
pushed 2
pushed 3
1
popped 3
popped 2
pushed 3
2
popped 3
3
代码工作正常,输出完全正确,但我真的不明白为什么在递归调用结束后,我在 if 中返回x
,所有以前的项目都被推入堆栈?push(x)
如何在没有底部元素的情况下再次将项目添加到堆栈中?
要了解代码如何通过push(x)
将元素推送到堆栈中,请考虑以下关于包含 N 个元素的队列的问答,其中 1 作为底部元素,N 作为顶部元素:
问:调用deQueue()
函数多少次?答:N次。第一次从main()
和 N-1 次递归。
问:deQueue()
方法中有一个返回x
的if
语句。此if
语句的条件满足多少次?答:只有一次。
问:那么,上述if
语句(包括push(x)
语句(后面的代码执行了多少次?答:N-1倍。
问:第一次执行push(x)
行是什么时候?答:它在其前一条语句时首次执行,即int item = deQueue();
已正常返回,没有任何递归。
问:在这种情况下(第一次调用push(x)
(,x
的价值是多少?答:如果deQueue()
正常返回且不再重复,则x
的值将为 1。但对于之前的最新递归,x
的值为 2。
问:下一次调用推送(x)
的x
值是多少?答案:3
问:其余的呢?答案:4, 5, ...N.
它通过临时存储元素直到到达底部来"弹出"堆栈的底部元素,然后在递归调用返回时将它们放回原处。
删除一个项目并保存以供以后使用:
int x = showtop()->data;
pop();
如果是底部项目,则返回它:
if (isempty()){
return x;
}
否则,让递归调用删除底部项目并将其提供给我们:
int item = deQueue();
现在堆栈包含除底部项目(item
(和我们删除的项目(x
(之外的所有项目,因此我们将删除的项目放回顶部:
push(x);
并传递我们从递归中获得的底部项目:
return item;
我怀疑让您感到困惑的是,deQueue
可能会将值返回到先前对deQueue
的调用,而不是直接返回到main
。
(从递归返回不像退出循环。
更具体地说,如果您的队列是
1 2 3
第一次调用将首先将1
存储在x
中,然后递归(堆栈现在2 3
(。
第二个调用将2
存储在其x
和递归 (3
( 中。
第三次调用删除3
,留下一个空堆栈,并将3
返回给其调用方。
然后,第二个调用推回它所花费的2
并返回3
(2
(。
然后,第一个调用推回1
并返回3
(1 2
(。
在你的deQueue()
函数中,你有这段代码(如果为真(退出程序:
if (isempty()) {
cout << "Q is empty";
exit(0);
}
几行之后,您就有:
if (isempty()){
return x;
}
这永远无法执行,因为您之前调用了exit(0)
。
- 返回递归调用和仅递归调用的区别
- 使用静态变量的递归调用的不同输出
- 复制构造函数中的递归调用
- 为什么编译器将其解析为函数指针而不是递归调用?
- 如何在 c++ 的类中递归调用函数方法?
- 了解使用堆栈实现队列的递归调用机制
- 如何通过函数指针递归调用类成员函数?
- 条件加倍时的递归调用
- 对可变参数函数的递归调用的链接器错误
- 将多个非原始递归调用转换为迭代解决方案
- 分段错误(核心转储)错误C++递归调用
- 无全局变量或功能参数的递归调用
- 在递归DP中,通过存储变量来分解递归调用:效率低下
- C - 为什么合并函数在递归调用后会逆转数组
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- C / SFML:使用两个递归调用在屏幕上打印凸形形状仅显示第一个递归调用中的形状,而不是第二个
- C++中具有 100000 个递归调用的运行时错误
- 递归调用可变参数模板函数重载时的不明确调用
- 如何在 c++ 中递归调用类
- 带有两个递归调用的递归算法的时间复杂性