`
mmdev
  • 浏览: 12914865 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

【100题】第五十七题 用两个栈实现队列

 
阅读更多

一,题目

某队列的声明如下:

template<typename T>  class CQueue
{
public:
      CQueue() {}
      ~CQueue() {}

      void appendTail(const T& node);  // append a element to tail
      void deleteHead();               // remove a element from head

private:
     T  m_stack1;
     T  m_stack2;
};



二,分析

栈:后入先出,插入删除在栈顶操作

队列:先入先出,插入在队尾,删除在队首


因此对队列进行的插入和删除操作都是在栈顶上进行;我们总是把新元素插入到队列的尾部,而从队列的头部删除元素。

1)stack1 入队队列 的栈

2)stack2 出队队列 的栈,如果出队列时候,stack2为空则将stack1中元素全部弹入stack2,然后出栈

三,参考代码如下:

template<typename T> void CQueue<T>::appendTail(const T& element)//入队 
{
      m_stack1.push(element);
}

template<typename T> void CQueue<T>::deleteHead() //出队 
{
      if(m_stack2.size() <= 0)
      {
            while(m_stack1.size() > 0)
            {
                  T& data = m_stack1.top();
                  m_stack1.pop();
                  m_stack2.push(data);
            }
      }

      assert(m_stack2.size() > 0);
      m_stack2.pop();
}


扩展:用两个队列实现一个栈?

思路:

1.有两个队列q1和q2,先往q1内插入a,b,c,这做的都是栈的push操作。
2.现在要做pop操作,即要得到c,这时可以将q1中的a,b两个元素全部dequeue并存入q2中,这时q2中元素为a,b,对q1再做一次dequeue操作即可得到c。
3.如果继续做push操作,比如插入d,f,则把d,f插入到q2中,
4.此时若要做pop操作,则做步骤2
5.以此类推,就实现了用两个队列来实现一个栈的目的。

注意在此过程中,新push进来的元素总是插入到非空队列中,空队列则用来保存pop操作之后的那些元素,那么此时空队列不为空了,原来的非空队列变为空了,总是这样循环。

对于push和pop操作,其时间为O(n).

#include <iostream>
#include <stack>
#include <assert.h>
using namespace std;

// 两个队列实现一个栈
template<typename T> class CStack
{
public:
    CStack() {}
    ~CStack() {}

    void mypush(const T& element);  

    void mypop();               


private:
    deque <T> m_queue1;
    deque <T> m_queue2;
};

template<typename T> void CStack<T>::mypop() //出栈 
{
    if (m_queue1.size() == 0)
    {
        while (m_queue2.size() > 1)
        {
            T& data = m_queue2.front();
            m_queue2.pop_front();
            m_queue1.push_back(data);
        }
        assert(m_queue2.size() == 1); //确保队列2内有一个元素
        T& result = m_queue2.front();
        m_queue2.pop_front();
        cout << result << endl;
    }

    else if (m_queue2.size() == 0)
    {
        while (m_queue1.size() > 1)
        {
            T& data = m_queue1.front();
            m_queue1.pop_front();
            m_queue2.push_back(data);
        }
        assert(m_queue1.size() == 1); //确保队列1内有一个元素
        T& result = m_queue1.front();
        m_queue1.pop_front();
        cout << result << endl;
    }
}


template<typename T> void CStack<T>::mypush(const T& element)//入栈 
{
    if (m_queue1.size() > 0)
    {
        m_queue1.push_back(element);
    }
    else if (m_queue2.size() > 0)
    {
        m_queue2.push_back(element);
    }
    else
    {
        m_queue1.push_back(element);
    }
}
int main()
{
    CStack<int> myStack;
    myStack.mypush(1);
    myStack.mypush(2);
    myStack.mypush(3);
    myStack.mypop();
    myStack.mypush(4);
    myStack.mypop();

    return 0;
}

分享到:
评论

相关推荐

    完整学习笔记:《剑指offer》Java版代码实现

    第七题 使用两个栈实现队列 测试7 第八题 寻求旋转带宽的最小数字 测试8 第九题 斐波那契数列的第n项(青蛙跳台阶) 测试9 第十题 二进制中1的个数 测试10 第十一题 数值的整数次方 测试11 第十二题 打印1到最大的n...

    C/C++程序员面试指南.杨国祥(带详细书签).pdf

    面试题12:能否用两个栈实现一个队列的功能 10.5 二叉树 面试题13:建立一个二叉树 面试题14:计算一棵二叉树的深度 面试题15:在二元树中找出和为某一值的所有路径 第11章 排序 11.1 插入排序 面试题1:编码实现...

    算法导论(part1)

    ·动态规划的两个应用(第15.1节和第15.5节)。 ·利用随机化和线性规划技术的近似算法(第35.4节)。 ·为了使更多的算法可以更早地在书中出现,第1版中有关数学背景知识的三章内容从第一部分移到了附录中,即现在...

    c语言题库问题和答案.docx

    循环结构习题:输入两个整数,输出它们的最大公约数 66%(4379/6621) 36% 2020-4-23 1008 顺序结构习题:求三个数的平均值 63%(4500/7162) 39% 2020-4-23 1009 顺序结构习题:求两点之间的距离 61%(4135/6812) 41% ...

    《剑指Offer》题目及代码.zip

    7. 用两个栈实现队列 8. 求旋转数组的最小数字 9. 斐波那契数列的第n项(青蛙跳台阶) 10. 二进制中1的个数 11. 数值的整数次方 12. 打印1到最大的n位数 13. O(1)时间删除链表节点 14. 使数组中的奇数位于偶数...

    《数据结构 1800题》

    6.数据结构中评价算法的两个重要指标是(时间复杂度和空间复杂度) 【北京理工大学 2001 七、1(2分)】 7. 数据结构是研讨数据的_(1)物理结构_和_(2)逻辑结构 _,以及它们之间的相互关系,并对与这种结构定义...

    计算机二级C语言考试题预测

    (62) 栈底至栈顶依次存放元素A、B、C、D,在第五个元素E入栈前,栈中元素可以出栈,则出栈序列可能是(D) A. ABCED B. DBCEA C. CDABE D. DCBEA (63) 线性表的顺序存储结构和线性表的链式存储结构分别是(B) A. 顺序...

    算法导论(part2)

    ·动态规划的两个应用(第15.1节和第15.5节)。 ·利用随机化和线性规划技术的近似算法(第35.4节)。 ·为了使更多的算法可以更早地在书中出现,第1版中有关数学背景知识的三章内容从第一部分移到了附录中,即现在...

    leetcode答案-Leetcode:LeetCode上的剑指offer题目;将它们分为十类,如下所示。并且有js编程语言的答案

    用两个栈实现队列 3、30.包含min函数的栈 4、59-I. 滑动窗口 5、59-II. 队列的最大值 三、哈希表 1、03. 数组中重复的数字 2、50. 第一个只出现一次的字符 四、链表 1、18. 删除链表的节点 2、22. 链表中倒数第k个...

    数据结构题

    4. 一个栈的输入序列为1 2 3,则下列序列中不可能是栈的输出序列的是( ) A. 2 3 1 B. 3 2 1 C. 3 1 2 D. 1 2 3 5. 采用开放定址法处理散列表的冲突时,其平均查找长度( )。 A.低于链接法处理冲突 B. 高于链接法...

    c语言经典案例

    实例173 使用指针连接两个字符串 245 实例174 用指针实现逆序存放数 组元素值 247 实例175 用指针数组构造字符串数组 248 实例176 用指针函数输出学生成绩 249 实例177 寻找相同元素的指针 251 实例178 查找成绩不...

    leetcode530-Algorithm-Daily:我想让算法练习成为每天和终生的习惯

    使用栈实现队列 第 232 章 58 数组中的第 K 个最大元素 第 215 章 57 将元素移动到结尾 算法专家 56 删除元素中的链接 力码 203 55 词搜索,前 K 个频繁元素 力码 79, 力码 347 54 数组除自身的乘积 第

    C程序范例宝典(基础代码详解)

    实例038 不用strcat连接两个字符串 46 实例039 删除字符串中连续字符 47 实例040 字符升序排列 49 实例041 在指定的位置后插入字符串 50 1.7 函数 51 实例042 求字符串中字符的个数 51 实例043 递归...

    计算机二级公共基础知识

    能使用二分法查找的线性表必须满足用顺序存储结构和线性表是有序表两个条件。 “有序”是特指元素按非递减排列,即从小到大排列,但允许相邻元素相等。下一节排序中,有序的含义也是如此。 对于长度为n的有序线性表...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例027 实现两个变量的互换(不借助 第3个变量) 37 2.3 条件语句 38 实例028 判断某一年是否为闰年 38 实例029 验证登录信息的合法性 39 实例030 为新员工分配部门 40 实例031 用Switch语句根据消费金额计算折扣 ...

    Java语言基础下载

    第五章:数组 71 学习目标 71 数组的描述 72 创建数组 72 多维数组 78 拷贝数组 80 内容总结 83 独立实践 84 第六章:继承 86 学习目标: 86 单继承(single inheritance) 87 访问控制 89 方法重载(method ...

Global site tag (gtag.js) - Google Analytics