剑指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 ...
随机推荐
- 关于新装ubuntu系统update失败和build-essential失败的解决办法
我是12月4日在新电脑上的vmware-workstation 10 上安装的ubuntu14.04LTS,但安装后再校园环境下总是build-essential失败,上网一查,说是要先update, ...
- EC读书笔记系列之6:条款11 在operator=中处理自我赋值
记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...
- php的系统常量
认识一下系统常量 系统常量是PHP已经定义好的常量,我们可以直接拿来使用,常见的系统常量有: (1)__FILE__ :php程序文件名.它可以帮助我们获取当前文件在服务器的物理位置. (2)__LI ...
- CDC不同模式在ODI体现系列之二 异步模式
CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...
- linux修改文本模式下的分辨率(CentOS6.4)
root登录 vi /boot/grub/menu.lst 看到如下界面: 红框全出位置为分辨率设置,设置参数如下: 保存 shutdown -r now
- Oracle EBS-SQL (SYS-10):锁定表查询.sql
/*死锁查询-1*/ SELECT o.object_name, l.session_id,l.process, l.locked_mode FROM v$locked_object l , dba_ ...
- javascript将异步校验表单改写为同步表单
同步表单校验的缺点 响应错误信息时,需要重新加载整个页面(虽然有缓存,客户端仍然需要通过http协议对比每个文件是否有更新,以保持文件最新) 服务器响应错误以后,用户之前所输入的信息全部丢失了,用户需 ...
- [Leetcode][Python]35: Search Insert Position
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 35: Search Insert Positionhttps://oj.le ...
- genymotion 模拟器 真是牛叉了 速度超快啊!!! 不解释了!建议大家速度去体验一把吧!
已经有人写了blog了 我就不再赘述了,详情去这里看去吧!! android genymotion模拟器怎么使用以及和google提供的模拟器性能对比 http://blog.csdn.net/ ...
- jstack命令使用
概述 jstack可用于导出java运用程序的线程堆栈.其基本使用语法为: jstack [-l] pid -l 选项用于打印锁的额外信息. 使用演示样例 以下这段代码执行之后会出现死锁现象(由于线程 ...