题目概述:用两个栈实现一个队列,请实现他的两个函数appendTail 和 deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
题目分析:我们知道栈结构的特点是“先进后出”,队列结构的特点的“先进先出”;仔细分析这道题,本道题的要求为将两个栈组合起来形成一个“先进先出”结构。
这里我们令第一个栈为stack1,第二个栈为stack2,首先插入一个元素a进入stack1,此时 stack1 中的元素有{a},我们再插入元素b和c,此时stack1中的元素为{a、b、c}(c为栈顶元素),而stack2为空(如图a所示);
此时我们考虑退出一个元素,由于要满足“先进先出”的原则,所以我们第一个退出的元素应该是a,但是a在stack1的栈底,不能直接取出元素,于时我们将stack1中的元素元素依次出栈,并依次压入stack2。此时stack1为空,stack2中的元素为{c、b、a}(a为栈顶元素);此时a为栈顶元素,便可出stack2,此时stack2中的元素为{c、b},stack1为空(如图b所示);
继续退出一个元素,由于b先于c入栈,故此时应该退出b,由于b位于stack2栈顶,可直接出栈(如图c所示);
接着我们插入一个元素d到stack1,此时stack1中的元素为{d},stack2中的元素为{c}(如图d所示);由于c比d先插入,而c位于stack2栈顶,故直接退出(如图e所示);
接下来如果继续插入元素的话便按照上述过程进行退出。
接下来我们做出总结,最开始我们任意选择一个stack进行插入(这里我们选择stack1),后面的元素均插入当前所选择的stack,当删除一个元素时,若stack2不为空,在stack2中的栈顶元素就是最先进入队列的元素;若stack2为空,我们便把stack1中的元素逐个出栈并压入stack2,此时直接退出stack2的栈顶元素即可。当两个栈均为空时,此时队列为空。
代码实现:
#include<iostream>
#include<stack>
using namespace std;
template<typename T>
class CQueue
{
public:
CQueue(){}
~CQueue(){}
void insertTail(const T &val)
{
stack1.push(val); //将元素插入stack1
}
T deleteHead()
{
if(stack2.size() <= 0) //如果stack2为空
{
while(!stack1.empty()) //如果stack1不为空
{
stack2.push(stack1.top()); //如果队列不为空,将stack1中的元素逐个插入stack2
stack1.pop();
}
}
if(stack2.size() == 0) //如果stack2为空,队列为空
throw new exception("queue is empty");
T head = stack2.top();
stack2.pop();
return head;
}
private:
stack<T> stack1;
stack<T> stack2;
};
int main()
{
CQueue<char> queue;
queue.insertTail('a'); //插入元素a
queue.insertTail('b'); //插入元素b
queue.insertTail('c'); //插入元素c
cout << "第1次出队元素:" << queue.deleteHead() << endl;
queue.insertTail('d'); //插入元素d
cout << "第2次出队元素:"<< queue.deleteHead() << endl;
cout << "第3次出队元素:"<<queue.deleteHead() << endl;
cout << "第4次出队元素:"<<queue.deleteHead() << endl;
return 0;
}
代码结果:
扩展:关于连个队列实现一个栈可以参考我的其他博文:https://blog.csdn.net/FDk_LCL/article/details/90045355