我们知道,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. [转载自 文顶顶]iOS开发UI篇—程序启动原理和UIApplication

    一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个应用都有自己的UIApplica ...

  2. 浅谈C中的指针和数组(三)

    上一个博客我们得到了一个结论: 指针和数组根本就是两个完全不一样的东西.只是它们都可以“以指针形式”或“以下标形式”进行访问.一个是完全的匿名访问,一个是典型的具名+匿名访问.一定要注意的是这个“以X ...

  3. 关于MySQL MyISAM 表并发

    MyISAM的锁调度 MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的.那么,一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?答案是写进程先获得 ...

  4. 读jQuery源码 jQuery.data

    var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; function internalData( elem, n ...

  5. threadid=1: thread exiting with uncaught exception (group=0x40db8930)

    异常信息如下: 07-26 17:23:49.521: W/dalvikvm(29229): threadid=1: thread exiting with uncaught exception (g ...

  6. cookie简介

    上例子 1.首先要用php创建cookie发送给客户端,利用setcookie()方法即可 <?php /* * * @Authors peng--jun * @Email 1098325951 ...

  7. [MUD]MUDLIB详解/MUDOS运行流程/最小MUDLIB/mud文件结构

    现在大部分中文MUD都是在东方故事(esII)基础上发展起来的,其目录结构基本一样, 也有个别MUD为了标新立异对个别目录换了个名字以示不同,但其实质没有什么变化. 这个做的最可恶的是xkx,把一个好 ...

  8. 用不动点组合子解递归(python实现)

    不动点组合子 Y = λf. (λx. f (x x)) (λx. f (x x)) θ = (λx. λy. (y(x x y))) (λx.λy.(y(x x y))) Y f = f (Y f) ...

  9. Microsoft Project 2010 简体中文专业版 + 永久激活密钥

    Microsoft Project 2010 简体中文专业版 + 永久激活密钥 (2014-02-17 11:44:16) 转载▼ 标签: 文化 分类: 学习 Microsoft Project已成为 ...

  10. 清风注解-Swift程序设计语言:Point1~5

    目录索引 清风注解-Swift程序设计语言 Point 1. Swift 风格的"Hello, world" 代码事例: println("Hello, world&qu ...