两个队列实现一个栈的两种方案
2016-04-16 09:10
288 查看
我们都知道,队列的特点是“先进先出”,而栈的特点是“先入后出”。
因为栈和队列插入元素的时候都是在尾部进行插入,这个所以插入操作很好解决。而队列是从队头开始删除的,栈是从栈顶删除元素,因此,我们需要考虑怎么将元素进行弹出,解决这个问题有两种方案。
方案一:
我们用一个队列作为主要维护栈的队列,该队列用来插入元素和弹出元素。
插入元素时,将元素直接插入到第一个队列的尾部。
弹出元素时:
(1)将第一个队列的除队尾元素以外的所有元素依次弹出并且插入到第二个队列中
(2)将第一个队列中剩下的那个元素弹出
(3)将第二个队列中的所有元素依次倒回到第一个队列中。
总的来说,弹出元素就是将元素导出,删除,倒回的过程。
这样就实现了将最后一个进入队列中的元素先弹出的目标。
入栈过程如下图:
出栈的过程如图:
方案二:
两个队列共同维护栈的入栈和出栈。
和方案一差不多,只是当删除了栈顶元素时,不需要将第二个队列中的元素倒回到第一个队列里。
出栈时,将不为空的队列中元素(出队尾元素)导出到另一个队列中,删除队尾元素。如下图:
1)入栈时只需判断一下哪个队列不为空,就插入到那个队列中,当两个队列都为空时,插入到哪个队列都可以。如下图:
程序如下:
因为栈和队列插入元素的时候都是在尾部进行插入,这个所以插入操作很好解决。而队列是从队头开始删除的,栈是从栈顶删除元素,因此,我们需要考虑怎么将元素进行弹出,解决这个问题有两种方案。
方案一:
我们用一个队列作为主要维护栈的队列,该队列用来插入元素和弹出元素。
插入元素时,将元素直接插入到第一个队列的尾部。
弹出元素时:
(1)将第一个队列的除队尾元素以外的所有元素依次弹出并且插入到第二个队列中
(2)将第一个队列中剩下的那个元素弹出
(3)将第二个队列中的所有元素依次倒回到第一个队列中。
总的来说,弹出元素就是将元素导出,删除,倒回的过程。
这样就实现了将最后一个进入队列中的元素先弹出的目标。
入栈过程如下图:
出栈的过程如图:
方案二:
两个队列共同维护栈的入栈和出栈。
和方案一差不多,只是当删除了栈顶元素时,不需要将第二个队列中的元素倒回到第一个队列里。
出栈时,将不为空的队列中元素(出队尾元素)导出到另一个队列中,删除队尾元素。如下图:
1)入栈时只需判断一下哪个队列不为空,就插入到那个队列中,当两个队列都为空时,插入到哪个队列都可以。如下图:
程序如下:
#pragma once #include<iostream> #include<queue> #include<assert.h> using namespace std; //使用两个队列实现一个栈 template<class T> class Stack { public: void Push(const T& d) { if (!_Qfirst.empty()) _Qfirst.push(d); else _Qsecond.push(d); } void Pop() { if (!_Qfirst.empty()) { _Pop(_Qfirst, _Qsecond); } else _Pop(_Qsecond, _Qfirst); } bool Empty() { if (_Qfirst.empty() && _Qsecond.empty()) { return true; } else return false; } T& Top() { if (!_Qfirst.empty()) { return _Qfirst.back(); } else return _Qsecond.back(); } size_t Size() { if (!_Qfirst.empty()) { return _Qfirst.size(); } else return _Qsecond.size(); } protected: void _Pop(queue<T>& Q1, queue<T>& Q2) { while (Q1.size()>1) { T& data = Q1.front(); Q2.push(data); Q1.pop(); } Q1.pop(); } protected: queue<T> _Qfirst; queue<T> _Qsecond; };
相关文章推荐
- Android与H5交互(java与js的交互)
- 手机号码,正则表达式的校验
- 《秦公求贤令》
- curl登陆后模拟登陆并访问登陆后的页面
- C++中capacity()用法总结
- IP/PV/UV/PR
- Linux fork和getpid语句详解
- 全网优秀IT博客导航
- 域名解析--什么是A记录、别名记录(CNAME)、MX记录、TXT记录、NS记录
- 设计模式 命令模式 之 管理智能家电
- 如何指定在创建派生类实例时调用的基类构造函数
- Python使用redis pool的一种单例实现方式
- bzoj 2560: 串珠子 子集dp
- knowledge base, knowledge graph
- reasoning
- 自定义圆头像
- LeetCode 294. Flip Game II(反转游戏II)
- mysql学习(列属性)
- semantic web
- Druid 配置