在《剑指Offer》中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即“用两个队列实现一个栈”。
  在计算机数据结构中,栈的特点是后进先出,即最后被压入(push)栈的元素会第一个被弹出(pop);队列的特点是先进先出,即第一个进入队列的元素将会被第一个弹出来。虽然栈和队列特点是针锋相对,但是两者却相互联系,可以互相转换。
  在“用两个队列实现一个栈”问题中,我们用两个队列的压入和弹出来模拟栈的压入和弹出。我们通过画图的手段把抽象的问题形象化。
  在上图中,我们先往栈内压入一个元素a。由于两个队列现在都是空,我们可以选择把a插入两个队列中的任一个。我们不妨把a插入queue1,接下来继续网栈内压入b,c两个元素。我们把它们都插入queue1。这个时候 queue1包含3个元素a,b,c,其中a位于队列的头部,c位于队列的尾部。
  现在我们考虑从栈内弹出一个元素。根据栈的后入先出的原则,最后被压入栈的c应该最先被弹出。由于c位于queue1的尾部,而我们每次只能从队列的头部删除元素,因此我们可以从queueu中依次删除a、b并插入到queue2中,再从queue1中删除c。这就相当于从栈中弹出元素c了。我们可以用同样的方法从栈内弹出元素b。
  接下来我们考虑从栈内压入一个元素d.此时queue1已经有了一个元素,我们就把d插入到queue1的尾部。如果我们再从栈内弹出一个元素,此时被弹出的应该是最后被压入的d.由于d位于queue1的尾部,我们只能先从头部删除queue1的元素并插入到queue2,直到queue1中遇到d再直接把它删除。
  注意:在上述思路中,两个队列存在全空队列和一个空队列的情况。所以,在程序中进入子函数第一步,要判断两个队列是否同时不为空(异常),增加程序的鲁棒性。另外,空栈删除元素要报异常,即两个队列均为空;
  程序实时更新在Github中: https://github.com/wylloong/TinyPrograms/blob/master/Coding%20Interviews/CStacks
               https://github.com/wylloong/TinyPrograms/blob/master/Coding%20Interviews/StackwithTwoQueues
  
************************************************************
  C++程序实现: 
// 面试题9附加题:用两个队列实现栈
// 题目:用两个队列实现一个栈。栈的声明如下,请实现它的两个函数appendTail
// 和deleteHead,分别完成在栈尾部插入结点和在栈头部删除结点的功能。 #pragma once
#include<queue>
#include<exception> using namespace std; template <typename T> class CStack
{
public:
CStack();
~CStack(); void appendTail(const T& node);
T deleteHead(); private:
queue<T> queue1;
queue<T> queue2;
}; template<typename T> CStack<T>::CStack()
{
} template<typename T> CStack<T>::~CStack()
{
} // 插入元素
template<typename T> void CStack<T>::appendTail(const T& node)
{
if (queue1.size() > && queue2.size() > )
{
//异常情况
}
else
{
//插入到非空队列,如果均为空则插入到queue2中
if (queue1.size() == )
{
queue2.push(node);
}
else
{
queue1.push(node);
}
}
} template<typename T> T CStack<T>::deleteHead()
{
if (queue1.size() == && queue2.size() == )
{
//异常情况
throw new exception("stack is empty");
}
T head;
if (queue1.size() > )
{
while (queue1.size()>)
{
//queue1中的元素依次删除,并插入到queue2中,其中queue1删除最后一个元素
//相当于从栈中弹出队尾元素 T& data = queue1.front();
queue1.pop();
queue2.push(data);
}
head = queue1.front();
queue1.pop();
}
else
{
while (queue2.size()>)
{
//queue2中的元素依次删除,并插入到queue1中,其中queue2删除最后一个元素
//相当于从栈中弹出队尾元素 T& data = queue2.front();
queue2.pop();
queue1.push(data);
}
head = queue2.front();
queue2.pop();
}
return head;
}
#include"CStacks.h"

// ====================测试代码====================
void test(char actual, char expected)
{
if (actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
} int main(int argc, char* argv[])
{
// 后进先出
CStack<char> stack; stack.appendTail('a');
stack.appendTail('b');
stack.appendTail('c'); char head = stack.deleteHead();
test(head, 'c'); head = stack.deleteHead();
test(head, 'b'); stack.appendTail('d');
head = stack.deleteHead();
test(head, 'd'); stack.appendTail('e');
head = stack.deleteHead();
test(head, 'e'); head = stack.deleteHead();
test(head, 'a'); //空栈删除,触发异常
//head = stack.deleteHead(); getchar();
return ;
}
 

《剑指Offer》附加题_用两个队列实现一个栈_C++版的更多相关文章

  1. 剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈

    剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()- ...

  2. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  3. 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先

    剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...

  4. 剑指Offer - 九度1512 - 用两个栈实现队列

    剑指Offer - 九度1512 - 用两个栈实现队列2013-11-29 21:23 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入 ...

  5. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  6. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  7. 剑指Offer - 九度1519 - 合并两个排序的链表

    剑指Offer - 九度1519 - 合并两个排序的链表2013-11-30 22:04 题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.(hi ...

  8. 《剑指Offer》题一~题十

    一.赋值运算符函数 题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString { public: CMyString(char *pData = nul ...

  9. 【剑指Offer】5、用两个栈实现队列

      题目描述:   用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型.   解题思路:   本题的基本意图是:用两个后入先出的栈来实现先入先出的队列.对于这个问题,我 ...

随机推荐

  1. Java: server/client 心跳机制实现 示例

    心跳机制 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制. 大部分CS的应用需要心跳机制.心跳机制一般在Server和Client都要实现,两者实现原理 ...

  2. 学习OpenResty的正确姿势

    前段时间老罗退出得到专栏事情闹得沸沸扬扬,另一位老罗也给出了合理的会员退费,感觉得到还是蛮贴心的.想想也是,毕竟精力有限,如今老罗也有了十亿的投资,集中精力做好手机才是主业.记得老罗刚开专栏那段时间很 ...

  3. JQuery中关于浏览器兼容性的问题

      前  言 LIUWE JQuery是一个特别强大的javascript代码库,,它的操作DOM的能力是相当强大的,JQuery可以说是支持各大主流浏览器,但是随着时代的不断发展,浏览器是在不断的更 ...

  4. GCD之线程挂起与恢复

    我们可以使用dispatch_suspend函数暂停一个queue以阻止它执行block对象;使用dispatch_resume函数继续dispatch queue.调用dispatch_suspen ...

  5. 在JavaScript中使用json.js:Ajax项目之GET请求(同步)

    1.用php编写一个提供数据的响应程序(phpdata.php) <?php $arr=array(1,2,3,4); //将数组编码为JSON格式的数据 $jsonarr=json_encod ...

  6. 第4章 同步控制 Synchronization ----Interlocked Variables

    同步机制的最简单类型是使用 interlocked 函数,对着标准的 32 位变量进行操作.这些函数并没有提供"等待"机能,它们只是保证对某个特定变量的存取操作是"一个一 ...

  7. hdu4686 Arc of Dream 2013 Multi-University Training Contest 9矩阵快速幂

    Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Tot ...

  8. MYSQL解压版安装说明

    一. zip格式,解压缩之后要进行配置.解压之后可以将该文件夹改名,放到合适的位置,比如把文件夹改名为MySQL(文件夹 MySQL下面就是 bin, data,my-default.ini 等) 二 ...

  9. C++PrimerPlus第6版 第四章——复合类型

    1,复合类型主要包含:数组.结构.联合.枚举.类.指针.引用等. 2,数组.长度必须确定.即编译阶段,数组的长度就得确定好.所以只能使用常量(#define.const)声明数组长度.如果使用变量声明 ...

  10. 最好用的css辅助工具——SASS&LESS

    前言 首先,小编给大家解释一下什么是SCSS和LESS,Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables).嵌套 (nested rules).混合 ...