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

两个栈实现队列 以及两个队列实现栈相关推荐

  1. 栈与队列2——两个栈组成队列

    题目 编写一个类,用两个栈实现一个队列,并实现队列的基本操作(add,poll,peek) 思路 一个栈stackPush作为正常压入的栈,一个栈stackPop作为弹出的栈,将stackPush中的 ...

  2. 两个栈实现一个队列,两个队列实现一个栈

    题目:用两个栈实现一个队列,用两个队列实现一个栈. 首先要了解栈和队列这两种数据结构各自的特点,栈是一种后入先出(Last In First Out,LIFO)的数据结构,队列是一种先进先出(Firs ...

  3. 两个栈实现一个队列与两个队列实现一个栈

    http://blog.csdn.net/z84616995z/article/details/19204529 两个栈实现一个队列: 原理方法:用一个栈为主栈,一个栈为辅助栈存放临时元素. 入队:将 ...

  4. 两个栈实现队列与两个队列实现栈

    1. 两个栈实现队列 实现一 思路 s1是入栈的,s2是出栈的. 入队列,直接压到s1是就行了 出队列,先把s1中的元素全部出栈压入到s2中,弹出s2中的栈顶元素:再把s2的所有元素全部压回s1中 实 ...

  5. C#数据结构:两栈实现队列,两队列实现栈

    两个栈实现队列:栈实现先进先出 栈1负责队尾,栈2负责队头 每次入队,栈2无元素且栈1无元素,入栈2:否则入栈1 每次出队,栈2有元素,出栈2顶:否则把全部栈1入栈2,再出栈2顶 bool Pop(r ...

  6. 算法与数据结构题目的 PHP 实现:栈和队列 由两个栈组成的队列

    思路:同样使用 PHP 的数组模拟栈.栈的特点是先进后出,队列的特点是先进先出,可以用第一个栈(StackPush)作为压入栈,压入数据的时候只往这个栈中压入数据,第二个栈作(StackPop)为弹出 ...

  7. javax消息队列_java实现消息队列的两种方式(小结)

    实现消息队列的两种方式 Apache ActiveMQ官方实例发送消息 下载解压后拿到java代码实例 然后倒入IDE 如下: 请认真阅读readme.md文件,大致意思就是把项目打成两个jar包,然 ...

  8. RabbitMQ自学之路(九)——RabbitMQ实现延时队列的两种方式

    一.什么是延时队列 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费. 二.延时队列应用于什么场景 场景一:在订单系统中,一个用户下单之后通常有30分钟的时间 ...

  9. 阻塞和非阻塞队列下两种生产者消费者实现

    队列可分为两种,一种是阻塞队列,一种是非阻塞队列. 阻塞队列和非阻塞队列的区别:阻塞队列可以阻塞,非阻塞队列不能阻塞,只能使用队列wait(),notify()进行队列消息传送.而阻塞队列当队列里面没 ...

  10. 顺序栈—栈顶指针的两种初始化

    采用顺序存储的栈称之为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针指示当前栈顶元素的位置. 下面给出两种栈顶指针定义的方式,讨论两种方式中在出栈.入栈代码上的不同: ...

最新文章

  1. 在64位Windows 7 激活BitDefender Internet Security 2010
  2. XCode6 生成prefix.pch文件
  3. 20155313 2016-2017-2 《Java程序设计》第二周学习总结
  4. MyBatisPlus注入公共Sql问题
  5. 3-7 基于SpringBoot的Apache Shiro环境快速搭建与配置实操
  6. A-Deeper-Understanding-of-Spark-Internals(Spark内核深入理解)
  7. R40 gpio 使用【原创】
  8. activiti学习笔记---常见异常
  9. c++内存优化:二级间接索引模式内存池
  10. C++之std::bind()用法
  11. “网红”Cat-1模组
  12. SAS安装后无法使用增强型编辑器问题解决方法
  13. 3D打印Gcode文件命令详解
  14. 如何获取iphone的UUID
  15. leetcode一些常用的工具的总结
  16. 浮士德头像裁剪flash版2016福利版
  17. SaaS平台产品架构设计
  18. 隐函数存在定理1的几何解释
  19. java中如何ping一个ip地址
  20. 快牛策略——嵌入式计算机

热门文章

  1. Hive复杂数据类型 struct
  2. 按位运算操作符底层实现原理
  3. Redis 基本数据类型
  4. 19.浏览器Window服务($window)
  5. Android使用ksoap2调用C#中的webservice实现图像上传
  6. linux下apache+php配置
  7. 洛谷P1821 [USACO07FEB]银牛派对Silver Cow Party
  8. 关于 Android Service 的介绍都在这了
  9. android多国语言使用
  10. linux awk数组使用