剑指offer——stack与queue的互相实现
我们知道,stack和queue是C++中常见的container。下面,我们来探究下如何以stack来实现queue,以及如何用queue来实现stack。
首先,先了解下stack与queue的基本属性。
一、stack
1,参数要求
stack模板类需要两个参数:一个元素类型,一个容器类型。容器类型缺省为deque。
2,基本操作
入栈:s.push(element);element加入栈顶。
出栈:s.pop(),栈顶元素被删除,无返回值。
访问栈顶:s.top()。取得栈顶元素。
判断栈空:s.empty()。栈空,返回true;非空,返回false。
长度判断:s.size()。返回栈张元素个数
二、queue
1,参数要求
queue模板类需要两个参数:一个元素类型,一个容器类型。容器类型缺省为deque。
2,基本操作
入队:q.push(element)。element加入到队列的末端。
出对:q.pop()。弹出(删除)队列的第一个元素(q.front())。无返回值。
访问队首:q.front(), 即最早被压入队列的元素。
访问队尾:q.back(),即最后被压入队列的元素。
判断队空:q.empty()。队空,返回true。
长度判断:q.size()。返回队列中元素个数。
三、两个stack实现queue
在基本了解了stack和queue这两个container后,我们来看看如何用stack实现queue。
如上所诉,queue包含了push(), pop(),front(),back(),empty()这些基本操作,现在的问题 就是如何用stack实现这些操作。
1,分析(已知stack A 和stack B)
入队:将元素进栈A
出队:判断B是否为空,如果为空,则将栈A中所有元素pop, 并push进 栈B,栈B出栈。
访问队首:栈B的栈顶。
访问队尾:如果栈A非空,队尾即栈A的栈顶(A.top());如果栈A为空,队尾为栈B的栈底(怎么取得栈B的栈底?利用第三个stack??)
队空:两个栈空,则队空。
长度:A.size(), B.size()
2,示意代码(未实现back())
class Stack2queue {
public:
void push(int node) {
stack1.push(node);
}
void pop() {
if (stack2.empty()) {
if (stack1.empty())
throw runtime_error("No elements");
else {
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
stack2.pop();
}
}else
stack2.pop();
}
int front() {
if (stack2.empty()) {
if (stack1.empty())
throw runtime_error("No elements");
else {
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
return stack2.top();
}
}else
return stack2.top();
}
bool myEmpty() {
if (stack1.empty() && stack2.empty())
return true;
else
return false;
}
private:
stack<int> stack1;
stack<int> stack2;
};
示意代码中未实现back()操作,笔者的想法是:若栈A为空,将stack B的元素pop出来,再push进 stack C。C的栈顶元素即是队尾。但是这样就新增了一个stack。不知道给广大博友是否有更好的方法?
四、两个queue实现stack
1,分析(queue A 和 queue B)
入栈:将元素push进队列A
出栈:判断队列A是否为空。空,则把队列B的元素出队列,进队列A,A再出队列进队列B,直到A中元素剩1,然后A.pop();非空,队列A中元素出队列进队列B,直到A中元素剩1,然后A.pop().
访问栈顶:与出栈类似,只不过由A.pop()B变为了A.front()或A.back(), 因为此时A只剩下一个元素。
判断栈空:queue1.empty() && queue2.empty()
长度:queue1.size() + queue2.size()
2,示意代码
class Queue2stack {
public:
void push(int);
void pop();
int top();
bool myempty();
private:
queue<int> queue1;
queue<int> queue2;
};
void Queue2stack::push(int element) {
queue1.push(element);
}
void Queue2stack::pop() {
if(!queue1.empty()) {
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
queue1.pop();
}
else {
if(!queue2.empty()) {
while (!queue2.empty()) {
queue1.push(queue2.front());
queue2.pop();
}
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
queue1.pop();
}
}
}
int Queue2stack::top() {
if(!queue1.empty()) {
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
return queue1.back();
}
else {
if(!queue2.empty()) {
while (!queue2.empty()) {
queue1.push(queue2.front());
queue2.pop();
}
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
return queue1.back();
}
}
throw runtime_error("No elements!");
}
bool Queue2stack::myempty() {
if(queue1.empty() && queue2.empty())
return true;
else
return false;
}
五、综合测试
上述讨论,介绍了stack和queue的相互实现。下面这个例子来检测我们的算法是否正确。
#include <iostream>
#include <stack>
#include <queue>
using namespace std; class Stack2queue {
public:
void push(int node) {
stack1.push(node);
} void pop() {
if (stack2.empty()) {
if (stack1.empty())
throw runtime_error("No elements");
else {
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
stack2.pop();
} }else
stack2.pop();
}
int front() {
if (stack2.empty()) {
if (stack1.empty())
throw runtime_error("No elements");
else {
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
return stack2.top();
} }else
return stack2.top();
} bool myEmpty() {
if (stack1.empty() && stack2.empty())
return true;
else
return false;
}
private:
stack<int> stack1;
stack<int> stack2;
}; class Queue2stack {
public:
void push(int);
void pop();
int top();
bool myempty();
private:
queue<int> queue1;
queue<int> queue2;
};
void Queue2stack::push(int element) {
queue1.push(element);
} void Queue2stack::pop() {
if(!queue1.empty()) {
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
queue1.pop(); }
else {
if(!queue2.empty()) {
while (!queue2.empty()) {
queue1.push(queue2.front());
queue2.pop();
}
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
queue1.pop();
} }
} int Queue2stack::top() {
if(!queue1.empty()) {
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
return queue1.back(); }
else {
if(!queue2.empty()) {
while (!queue2.empty()) {
queue1.push(queue2.front());
queue2.pop();
}
while(queue1.size() > ) {
queue2.push(queue1.front());
queue1.pop();
}
return queue1.back();
}
}
throw runtime_error("No elements!"); } bool Queue2stack::myempty() {
if(queue1.empty() && queue2.empty())
return true;
else
return false;
}
int main()
{
// stack to queue
Stack2queue s2q;
for (int i = ; i < ; ++i) {
s2q.push(i);
}
while (!s2q.myEmpty()) {
cout << s2q.front() << ' ';
s2q.pop();
} //queue to stack
cout << endl;
Queue2stack q2s;
for (int i = ; i < ; ++i) {
q2s.push(i);
}
while(!q2s.myempty()) {
cout << q2s.top() << ' ';
q2s.pop();
}
//system("pause");
return ;
}
实验结果:

我们看到,我们很好的用stack模拟了queue,达到了先进先出的效果;同样,我们也很好的用queue模拟了stack,先进后出的效果。
不过,值得考虑的是,笔者在用stack实现queue时,没有实现back()操作。各位博友有啥好想法呢?
剑指offer——stack与queue的互相实现的更多相关文章
- 面试题目——《剑指Offer》
1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...
- 剑指offer习题集2
1.把数组排成最小的数 class Solution { public: static bool compare(const string& s1, const string& s2) ...
- [读]剑指offer
研二的开始找工作了,首先祝愿他们都能够找到自己满意的工作.看着他们的身影,自问明年自己这个时候是否可以从容面对呢?心虚不已,赶紧从老严那儿讨来一本<剑指offer>.在此顺便将自己做题所想 ...
- 《剑指Offer》附加题_用两个队列实现一个栈_C++版
在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...
- 剑指offer面试题-Java版-持续更新
最近在用Java刷剑指offer(第二版)的面试题.书中原题的代码采用C++编写,有些题的初衷是为了考察C++的指针.模板等特性,这些题使用Java编写有些不合适.但多数题还是考察通用的算法.数据结构 ...
- 《剑指offer》全部题目-含Java实现
1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. publi ...
- 剑指offer(javascript实现)
1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. funct ...
- 《剑指offer(第二版)》面试题60——n个骰子的点数
一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...
- 剑指offer 第十二天
58.对称的二叉树 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. /* public class TreeNode { int val ...
随机推荐
- Windows下C++多线程同步与互斥简单运用
1. 互斥量,Mutex #include <Windows.h> #include <iostream> using namespace std; DWORD WINAPI ...
- Git 系列(三):建立你的第一个 Git 仓库
现在是时候学习怎样创建你自己的 Git 仓库了,还有怎样增加文件和完成提交. 在本系列前面的文章中,你已经学习了怎样作为一个最终用户与 Git 进行交互:你就像一个漫无目的的流浪者一样偶然发现了一个开 ...
- EasyUI在MVC4中需要部分刷新页面时load()后页面变形问题!
最近在使用MVC4与EasUI过程中遇到些容易导致界面变形的问题,纠结了很久,但其实当发现问题在哪里时,倒觉得最终还是自己对MVC4的概念没把握好,OK,show time. 本示例Contact ...
- J2SE知识点摘记(十四)
1. 字符流 Reader是定义java的流式字符输入模式的抽象类,该类所有方法在出错的情况下都将引发IOException异常. Int read(char buffer[]) ...
- DRAM与NAND Flash产业六大趋势预测分析
集邦科技(TrendForce)旗下的分析部门DRAMeXchange的研究,针对对DRAM与NANDFlash产业的长久观察下,提出了对2012-2015年间产业发展的六大趋势预测: 趋势一 ...
- 在windows下进行linux开发:利用Vagrant+virtualbox(ShowDoc与mp3dish的作者)
1,介绍Vagrant 我们做web开发的时候经常要安装各种本地测试环境,比如apache,php,mysql,redis等等.出于个人使用习惯,可能我们还是比较习惯用windows.虽然说在wind ...
- 服务没有mysql
你安装了mysql没有,没有就先安装,安装好mysql以后,在bin目录下有个mysqld.exe,运行这个程序就可以添加mysql服务,但是运行这个程序需要使用参数,否则就会以命令行窗口形式启动MY ...
- JavaEE Tutorials (16) - Java消息服务概念
16.1JMS API概述198 16.1.1什么是消息传送198 16.1.2什么是JMS API199 16.1.3何时使用JMS API199 16.1.4Java EE平台如何使用JMS AP ...
- iOS中的retainCount
我们都知道iOS中采用引用计数的技术来管理内存,当一个对象没有任何一个地方引用的时候会自动释放,此时的retainCount为0,而且提供了一个-(NSInteger)retainCount的方法来获 ...
- http://docs.aliyun.com/#/rds/best-practices/collocation&security
http://docs.aliyun.com/#/rds/best-practices/collocation&security