我们知道,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的互相实现的更多相关文章

  1. 面试题目——《剑指Offer》

    1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...

  2. 剑指offer习题集2

    1.把数组排成最小的数 class Solution { public: static bool compare(const string& s1, const string& s2) ...

  3. [读]剑指offer

    研二的开始找工作了,首先祝愿他们都能够找到自己满意的工作.看着他们的身影,自问明年自己这个时候是否可以从容面对呢?心虚不已,赶紧从老严那儿讨来一本<剑指offer>.在此顺便将自己做题所想 ...

  4. 《剑指Offer》附加题_用两个队列实现一个栈_C++版

    在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...

  5. 剑指offer面试题-Java版-持续更新

    最近在用Java刷剑指offer(第二版)的面试题.书中原题的代码采用C++编写,有些题的初衷是为了考察C++的指针.模板等特性,这些题使用Java编写有些不合适.但多数题还是考察通用的算法.数据结构 ...

  6. 《剑指offer》全部题目-含Java实现

    1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. publi ...

  7. 剑指offer(javascript实现)

    1.二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. funct ...

  8. 《剑指offer(第二版)》面试题60——n个骰子的点数

    一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...

  9. 剑指offer 第十二天

    58.对称的二叉树 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. /* public class TreeNode { int val ...

随机推荐

  1. Windows 去掉启动时的放大镜

    控制面板-轻松访问中心-使计算机更易于显示不勾选 启用放大镜

  2. centos5.5用phpstudy一键安装配置虚拟主机后,yum配置代理服务器squid

    最近因为工作需要,开发站点需要在lamp环境下跑网站,于是在win7上跑虚拟机装了一个centos5.5的linux 并用集成环境配置了一个lamp环境,这里用的是phpstudy的一键安装包,并配置 ...

  3. 基于位运算符的IP和数值转换

    直接上代码: $str = '192.168.2.100'; echo 'IP:',$str,'<hr />'; $int = ip_long($str); echo $int,'< ...

  4. spoj TSUM - Triple Sums fft+容斥

    题目链接 首先忽略 i < j < k这个条件.那么我们构造多项式$$A(x) = \sum_{1现在我们考虑容斥:1. $ (\sum_{}x)^3 = \sum_{}x^3 + 3\s ...

  5. mini-httpd源码分析-tdate_parse.h

    ///关联字符串和整数 struct strlong { char* s; long l; }; ///将字符串中的大写字母转换成小写字母 static void pound_case(char* s ...

  6. RedMine 版本管理工具

    一.介绍: Redmine 是一个开源的.基于Web的项目管理和缺陷跟踪工具.它用日历和甘特图辅助项目及进度可视化显示.同时它又支持多项目管理.Redmine是一个自由开放 源码软件解决方案,它提供集 ...

  7. android 栈方式退出

    介于list退出方式会使内存溢出,使用自己维护栈的方式. 参考: http://www.2cto.com/kf/201312/265523.html http://www.cnblogs.com/ma ...

  8. J2SE知识点摘记(七)

    1.        枚举的用法 enum 枚举名{枚举值表标};例子:"enum weekday{sun,mon,tue,wed,fri,sat}a,b,c;" For循环语句中使 ...

  9. Ubuntu下,在Eclipse中使用JNI调用ffmpeg

    Android的应用层开发大部分还是采用JAVA,如果想使用ffmpeg库,就必须利用JNI,使得Java可以调用C/C++的库. JNI其实就是定义的一个转接接口,可以让Java的代码调用C/C++ ...

  10. [Leetcode][Python]30: Substring with Concatenation of All Words

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 30: Substring with Concatenation of All ...