我们知道,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. Oracle的用户管理,授权及备份

    一.用户进行授权的操作 创建用户:刚刚创建的用户并没有任何权限 CREATE USER 用户名 indentife BY 密码 授权:  GRANT 权限1,权限2... TO 用户权限有:CREAT ...

  2. iOS通知NSNotificationCenter

    NSNotificationCenter消息通信 作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的. 注册通知:即要在什么地方接受消息 [[NSNotificat ...

  3. OC中给我们提供的一个技术:谓词(NSPredicate).note

    OC中给我们提供的一个技术:谓词(NSPredicate)OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到 ...

  4. 浅谈树链剖分(C++、算法、树结构)

    关于数链剖分我在网上看到的有几个比较好的讲解,本篇主要是对AC代码的注释(感谢各位witer的提供) 这是讲解 http://www.cnblogs.com/kuangbin/archive/2013 ...

  5. Myeclipse 常用操作(待补充)

    1.更改背景色 进入myeclipse工作区,选择window->Preferences->General->Editors->Text Editors->Backgro ...

  6. C#时间日期操作

     一.C# 日期格式 DateTime dt = DateTime.Now; dt.ToString();//2005-11-5 13:21:25 dt.ToFileTime().ToString() ...

  7. Atom power-mode

    最近看到很多大牛都在用这个酷炫狂拽掉渣天的插件,于是就默默地git了一波.实际结果就是机械键盘加上砰砰砰砰,根本停不下来有没有. 建议(ˉ(∞)ˉ) :视力2.0的同学不建议使用,眼瞎的同学用就用吧, ...

  8. Android GridView 二维布局界面

    GridView用于在界面上按行.列分布的方式来显示多个组件. <LinearLayout xmlns:android="http://schemas.android.com/apk/ ...

  9. hadoop笔记之Hive的管理(远程登录方式)

    Hive的管理(三) Hive的管理(三) Hive的远程服务 远程服务启动方式 端口号10000 启动方式:hive --service hiveserver (注意:以JDBC或ODBC的程序登录 ...

  10. JS中特殊句子-for in

    for(var i=0;i<len;i++)这样的用法一般都可以用for in 来替代. 例如: var a = ["a","b","c&quo ...