在《剑指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. 201521123022 《Java程序设计》第三周学习总结

    1.本周学习总结 2.书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; pu ...

  2. Sublime使用Ctrl+`作为快捷键弹出Console没有反映的解决办法

    很多Sublime新人都遇到了这个问题,到网上搜,信息很片面,而且不少都是旧版本的.于是有了这篇文章.       默认Sublime使用Ctrl+`作为快捷键弹出Console,但不同的系统抑或安装 ...

  3. 201521123054《java程序设计》第12周学习总结

    1. 本周学习总结 2. 书面作业 1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读) 1.1 生成的三个学生对象,使用PrintWriter的printl ...

  4. 陈敏 Java课设实验报告

    1.团队课程设计博客链接 http://www.cnblogs.com/ohanna/p/7064305.html 2.个人负责模板或任务说明 1.负责完成主界面 2.随机数的产生, 3.数字大小的比 ...

  5. linux c函数指针的应用

    头文件:1.h #include<stdio.h> int nul_func(); int test1(int a,int b); int test2(int a,int b,int c) ...

  6. PHP 动态调整内存限制

    最近公司的一个PHP项目在操作大文件的时候总是抛出这个异常 Fixing PHP Fatal Error: Allowed Memory Size Exhausted 经过一番调试后发现是达到了PHP ...

  7. Spring-mvc配置“/”路径过滤问题

    首先大家都知道"/*"可以匹配所有url,包括带扩展名的,一般只用在过滤器上. 一般Spring-mvc的核心 <servlet> <servlet-name&g ...

  8. PHP实现页面静态化

    1.通过buffer来实现   需要用file_put_contents ob_get_clean()等内置函数   ob_start (); include "filterpost.htm ...

  9. [AHOI2001]质数和分解

    [AHOI2001]质数和分解 题目描述 任何大于 1 的自然数 n 都可以写成若干个大于等于 2 且小于等于 n 的质数之和表达式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形 ...

  10. 转载 iOS拦截导航栏返回按钮事件的正确方式

    原文链接:http://www.jianshu.com/p/25fd027916fa 当我们使用了系统的导航栏时,默认点击返回按钮是 pop 回上一个界面.但是在有时候,我们需要在点击导航栏的返回按钮 ...