两个栈实现队列 以及两个队列实现栈
1.用两个栈来实现队列,栈是先进后出的,队列是先进先出的,这时,我们可以用stack1来专门入栈,stack2来专门出栈,具体地:
入队:直接入栈到stack1
出队:检测stack2是否为空,如果为空,则将stack1的所有元素移动到stack2中,
再次判断stack2是否为空,如果为空抛出异常;
如果非空,将stack2的栈顶元素出队。
代码如下:
#include <iostream> #include <stack> using namespace std; //用两个栈实现一个队列stack1专门用来入队 stack2专门用来出队 template<class T>class Queue { public:Queue(void){};~Queue(void){};void AppendTail(const T &ele);T DeleHead(); private:stack<T>stack1;stack<T>stack2;};//stack1专门用来入栈 template<class T> void Queue<T>::AppendTail(const T &ele) {stack1.push(ele); } //stack2作为临时缓冲,将stack1入栈的元素逆序 然后出栈即可实现先入先出 template<class T> T Queue<T>::DeleHead() {if (stack2.size()<=0)//stack2空 则将stack1的元素都放在stack2中 {while (stack1.size()>0){T node=stack1.top();stack2.push(node);stack1.pop();}}if (stack2.size()==0)//判断栈是否为空 {cout<<"empty"<<endl;throw new exception();}T RetNode =stack2.top();//返回stack2的栈顶元素stack2.pop();//出栈return RetNode; }void main() {Queue<int>*pQu=new Queue<int>();pQu->AppendTail(1);pQu->AppendTail(2);pQu->AppendTail(3);cout<<pQu->DeleHead()<<endl;pQu->AppendTail(4);pQu->AppendTail(5);cout<<pQu->DeleHead()<<endl;cout<<pQu->DeleHead()<<endl;cout<<pQu->DeleHead()<<endl;cout<<pQu->DeleHead()<<endl;cout<<pQu->DeleHead()<<endl;}
队列是先进先出的,而栈是后进先出的,那么我们如何用两个队列实现栈的操作呢?
方法一:
我们可以让queue1专门用来入栈和出栈操作,让queue2作为储存queue1的n-1个元素,也就是除了最后一个入队元素,然后将queue1中的最后元素出列,然后将queue2中的 n-1个元素放回queue1.
思路:
q1是专职进出栈的,q2只是个中转站
入栈时:直接入队列q1即可
出栈时:把q1的除最后一个元素外全部转移到队q2中,然后把刚才剩下q1中的那个元素出队列。之后把q2中的全部元素转移回q1中。
如下图所:
#include <queue>
#include <iostream>
using namespace std;
template <class T>
class Stack
{
public:Stack(){};~Stack(){};void StackPush(const T&data);T StackPop();
private:queue<T>que1;queue<T>que2;
};
//que1专门用来入栈
template<class T> void Stack<T>::StackPush(const T&data)
{que1.push(data);
}
//que2作为临时存储que1的多余变量,当出栈后要将所有元素还给que1
template<class T> T Stack<T>::StackPop()
{if (que1.size()<=0){cout<<"empty"<<endl;throw new exception("empty");}else//que1的变量大于等于1个时{while(que1.size()>1)//将最先入n-1个元素的存que2中{que2.push(que1.front());que1.pop();}T RetData=que1.front();//返回最后入的元素que1.pop();while(que2.size()>0)//再将que2的元素存回que1{que1.push(que2.front());que2.pop();}return RetData;}
}void main()
{Stack<int > *pSt=new Stack<int >();pSt->StackPush(1);pSt->StackPush(2);pSt->StackPush(3);cout<<pSt->StackPop()<<endl;cout<<pSt->StackPop()<<endl;cout<<pSt->StackPop()<<endl;
// cout<<pSt->StackPop()<<endl;//抛异常
}
结果如下图:
然后我们发现,如果队列中元素较多时,每当移除一个元素,那么剩余的n-1个元素都要拷贝进queue2,然后再从queue2拷进queue1,这样增加了时间复杂度,那么能不能有其他更好的办法呢?
方法二:
让两个栈都当做出栈或者入栈的队列,当入栈时候,先选定一个que1入栈,当出栈时候将que1的n-1个元素移动que2。那么下一次出栈的队列为que2,再将n-1个元素移动到que1,依次.....
那么入栈时候该选择哪个呢?很显然,入栈也是来回变的,每当有一次出栈操作时,下次入栈时所选的队列都会改变,这时候我们只需要一个标志位flag来选定该入哪个队列就好了。
代码如下:
#include <queue> #include <iostream> using namespace std; template <class T> class Stack { public:Stack(){};~Stack(){};void StackPush(const T&data);T StackPop(); private:queue<T>que1;queue<T>que2;static bool flag;//用来标识该在哪个队列入栈的标识 };template<class T> bool Stack<T>::flag=true;//初始化为TRUE 在que1中入栈 template<class T> void Stack<T>::StackPush(const T&data) {queue<T>*quTemp=NULL;//用于指向要入栈的队列,注意初始化格式if (flag)//标识用来决定该入栈到哪个队列 {quTemp=&que1;}else {quTemp=&que2;}quTemp->push(data); }template<class T> T Stack<T>::StackPop() {flag=!flag;//将标识取反queue<T>*popTemp=NULL;//用于出栈的临时队列queue<T>*saveTemp=NULL;//用于保存n-1个多余变量的队列if (que1.size()>=1){popTemp=&que1;saveTemp=&que2;}else{popTemp=&que2;saveTemp=&que1;}if (popTemp->size()<=0){cout<<"Empty"<<endl;throw new exception("the stack is empty");}while(popTemp->size()>1)//出栈的队列中元素大于1个 移动到另一个队列中 {saveTemp->push(popTemp->front());popTemp->pop();}T RetVal=popTemp->front();//返回最后一个元素popTemp->pop();return RetVal; }void main() {Stack<int> *pSt=new Stack<int>();pSt->StackPush(1);pSt->StackPush(2);pSt->StackPush(3);cout<<pSt->StackPop()<<endl;cout<<pSt->StackPop()<<endl;pSt->StackPush(4);pSt->StackPush(5); cout<<pSt->StackPop()<<endl;cout<<pSt->StackPop()<<endl;cout<<pSt->StackPop()<<endl;}
运行结果如下图所示:
转载于:https://www.cnblogs.com/mu-tou-man/p/3954032.html
两个栈实现队列 以及两个队列实现栈相关推荐
- 栈与队列2——两个栈组成队列
题目 编写一个类,用两个栈实现一个队列,并实现队列的基本操作(add,poll,peek) 思路 一个栈stackPush作为正常压入的栈,一个栈stackPop作为弹出的栈,将stackPush中的 ...
- 两个栈实现一个队列,两个队列实现一个栈
题目:用两个栈实现一个队列,用两个队列实现一个栈. 首先要了解栈和队列这两种数据结构各自的特点,栈是一种后入先出(Last In First Out,LIFO)的数据结构,队列是一种先进先出(Firs ...
- 两个栈实现一个队列与两个队列实现一个栈
http://blog.csdn.net/z84616995z/article/details/19204529 两个栈实现一个队列: 原理方法:用一个栈为主栈,一个栈为辅助栈存放临时元素. 入队:将 ...
- 两个栈实现队列与两个队列实现栈
1. 两个栈实现队列 实现一 思路 s1是入栈的,s2是出栈的. 入队列,直接压到s1是就行了 出队列,先把s1中的元素全部出栈压入到s2中,弹出s2中的栈顶元素:再把s2的所有元素全部压回s1中 实 ...
- C#数据结构:两栈实现队列,两队列实现栈
两个栈实现队列:栈实现先进先出 栈1负责队尾,栈2负责队头 每次入队,栈2无元素且栈1无元素,入栈2:否则入栈1 每次出队,栈2有元素,出栈2顶:否则把全部栈1入栈2,再出栈2顶 bool Pop(r ...
- 算法与数据结构题目的 PHP 实现:栈和队列 由两个栈组成的队列
思路:同样使用 PHP 的数组模拟栈.栈的特点是先进后出,队列的特点是先进先出,可以用第一个栈(StackPush)作为压入栈,压入数据的时候只往这个栈中压入数据,第二个栈作(StackPop)为弹出 ...
- javax消息队列_java实现消息队列的两种方式(小结)
实现消息队列的两种方式 Apache ActiveMQ官方实例发送消息 下载解压后拿到java代码实例 然后倒入IDE 如下: 请认真阅读readme.md文件,大致意思就是把项目打成两个jar包,然 ...
- RabbitMQ自学之路(九)——RabbitMQ实现延时队列的两种方式
一.什么是延时队列 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费. 二.延时队列应用于什么场景 场景一:在订单系统中,一个用户下单之后通常有30分钟的时间 ...
- 阻塞和非阻塞队列下两种生产者消费者实现
队列可分为两种,一种是阻塞队列,一种是非阻塞队列. 阻塞队列和非阻塞队列的区别:阻塞队列可以阻塞,非阻塞队列不能阻塞,只能使用队列wait(),notify()进行队列消息传送.而阻塞队列当队列里面没 ...
- 顺序栈—栈顶指针的两种初始化
采用顺序存储的栈称之为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针指示当前栈顶元素的位置. 下面给出两种栈顶指针定义的方式,讨论两种方式中在出栈.入栈代码上的不同: ...
最新文章
- 在64位Windows 7 激活BitDefender Internet Security 2010
- XCode6 生成prefix.pch文件
- 20155313 2016-2017-2 《Java程序设计》第二周学习总结
- MyBatisPlus注入公共Sql问题
- 3-7 基于SpringBoot的Apache Shiro环境快速搭建与配置实操
- A-Deeper-Understanding-of-Spark-Internals(Spark内核深入理解)
- R40 gpio 使用【原创】
- activiti学习笔记---常见异常
- c++内存优化:二级间接索引模式内存池
- C++之std::bind()用法
- “网红”Cat-1模组
- SAS安装后无法使用增强型编辑器问题解决方法
- 3D打印Gcode文件命令详解
- 如何获取iphone的UUID
- leetcode一些常用的工具的总结
- 浮士德头像裁剪flash版2016福利版
- SaaS平台产品架构设计
- 隐函数存在定理1的几何解释
- java中如何ping一个ip地址
- 快牛策略——嵌入式计算机