如何用两个栈实现一个队列,以及用两个队列实现一个栈

开始

再开始开始实现之前,首先将定读者已经理解了栈和队列的区别。

如果不理解的话,可以先看看这一篇,传送门:【算法】7 分不清栈和队列?一张图给你完整体会

用两个栈实现一个队列

这本来就是一道面试题,所以如果你感兴趣的话可以先自己实现一遍。这是队列的声明:

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

    void appendTail(const T& node);
    T deleteHead();

private:
    stack<T> stack1;
    stack<T> stack2;
};

你要补充的就是在队列尾部插入结点和在队列头部删除结点的功能。

下面是图片演示过程,以及具体代码实现。

  • 插入a,b,c:往stack1中依次压入了a,b,c
  • 删除队列头:将c,b依次从stack1弹出和压入stack2
  • 删除队列头:将b从stack2中弹出
  • 插入d:往stack1中压入d
  • 删除队列头:将c从stack2中弹出
template <typename T> void CQueue<T>::appendTail(const T& element){
    stack1.push(element);
}

template <typename T> T CQueue<T>::deleteHead(){
    if(stack2.size() <= 0){
        while(stack1.size > 0){
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    if(stack2.size() == 0){
        throw new exceptions("queue is empty");
    }

    T head = stack2.top();
    stack2.pop();

    return head;
}

用两个队列实现一个栈

写完了上面的代码,是不是也想换过来试一试呢?

同样是图片演示,以及具体代码实现。

  • 插入a:向queue1中压入a
  • 插入b:向queue1中压入b之前,先将a压入到queue2中,再将a从queue1中弹出
  • 插入c,d:同上过程,最后如图所示
  • 从栈顶删除d:将queue1中的d弹出
  • 从栈顶删除c(1):queue1为空,此时先将a和b依次压入queue1,再从queue2中弹出
  • 从栈顶删除c(2):将queue2中的c弹出,并将queue1中的a和b弹出再压入queue2
template <typename T> class CStack {
public:
    CStack(void);
    ~CStack(void);

    void appendTail(const T& node);
    T deleteHead();

private:
    queue<T> queue1;
    queue<T> queue2;
};

template <typename T> CStack<T>::CStack(void) {

}

template <typename T> CStack<T>::~CStack(void) {

}

template <typename T> void CStack<T>::appendTail(const T& element) {
    if (queue1.size() >= 1) {
        T& data = queue1.front();
        queue1.pop();
        queue2.push(data);
    }
    queue1.push(element);
}

template <typename T> T CStack<T>::deleteHead() {
    T head;
    if (queue1.size() >= 1) {
        head = queue1.front();
        queue1.pop();
    }
    else if (queue1.size() == 0&&queue2.size() > 0) {
        while (queue2.size() > 1) {
            T& data = queue2.front();
            queue2.pop();
            queue1.push(data);
        }
        head = queue2.front();
        queue2.pop();
        while (queue1.size() > 0) {
            T& data = queue1.front();
            queue1.pop();
            queue2.push(data);
        }
    }
    else {
        throw new exception("stack is empty");
    }
    return head;
}
时间: 2024-08-11 20:03:23

如何用两个栈实现一个队列,以及用两个队列实现一个栈的相关文章

安卓 验证 密码-如何用安卓实现焦点离开EditText时,验证两次输入密码是否一致。

问题描述 如何用安卓实现焦点离开EditText时,验证两次输入密码是否一致. 在做一个注册界面,类似于https://mail.sina.com.cn/register/regmail.php 求教:在输入密码和确认密码后,点击到手机号码中时就验证两次密码是否一致.要逻辑清晰点儿的代码.先谢谢大神! 解决方案 EditText a=(EditText)findViewById(R.id.a); a.setOnFocusChangeListener(new OnFocusChangeListen

一个简易的Java多页面队列爬虫程序_java

之前写过很多单页面python爬虫,感觉python还是很好用的,这里用java总结一个多页面的爬虫,迭代爬取种子页面的所有链接的页面,全部保存在tmp路径下. 一. 序言 实现这个爬虫需要两个数据结构支持,unvisited队列(priorityqueue:可以适用pagerank等算法计算出url重要度)和visited表(hashset:可以快速查找url是否存在):队列用于实现宽度优先爬取,visited表用于记录爬取过的url,不再重复爬取,避免了环.java爬虫需要的工具包有http

shell-SHELL怎么实际现一个行内容 匹配两个字符之间的内容,一行有多个配置内容。

问题描述 SHELL怎么实际现一个行内容 匹配两个字符之间的内容,一行有多个配置内容. 举例说明:12aa34bb56aa78bb90匹配字符是aa bb 要取得aa bb之间的内容,34,78; 在这先谢谢大神们了. 解决方案 linux sed 替换两个字符之间的内容

一个页面上连接两种不同数据库 是否可行

一个页面上连接两种不同数据库,进行操作...不知道,是否可行? 有这可能吗? 当然可以 mssql ConnStr = "driver={SQL Server};server=192.168.1.110;database=news;uid=sa;pwd=123456" Set conn = Server.CreateObject("ADODB.Connection") conn.Open ConnStr mysql set myconn = server.creat

Excel中制作一个项目文件目录的两种方法

  Excel中制作一个项目文件目录的两种方法.如下图所示,就是一个项目文件夹内的所有文件: 接下来,先提取文件名称. 如果文件比较少,可以直接输入到Excel文档中,但是如果文件比较多,就要想想办法了. 方法一 在工程文件夹内,新建一个记事本文档,输入下面的内容后保存: DIR *.* /B >目录.TXT 将记事本文档的后缀名.txt 修改为.bat 然后双击这个文件,就会得到一个名为"目录"的记事本文件,里面会包含当前文件夹内的所有文件名. 这样就可以将目录中的文档名复制到

c++-“一个指针指向某对象,同时另一个指针指向另外对象的下一地址,两个指针可能相等”是怎么回事?

问题描述 "一个指针指向某对象,同时另一个指针指向另外对象的下一地址,两个指针可能相等"是怎么回事? <C++ Primer>第五版,中文版.p50. 需要注意的是,一个指针指向某对象,同时另一个指针指向另外对象的下一地址,此时也有可能出现这两个指针值相同的情况,即指针相等. 解决方案 另外对象和某对象正好相邻,另外对象的下一对象正好是某对象. 解决方案二: 用一个指向int的指针来存储一个对象的地址.当指针A指向一个对象H的时候对象指针创建时的一个小插曲 解决方案三: 两

java方法-java一个方法形参有两个,如何在调用的时候只传入一个参数

问题描述 java一个方法形参有两个,如何在调用的时候只传入一个参数 如题,有一个方法里两个形参,我另一个文件类中一个方法想要那个方法的返回值,可是第二个参数在这里用不到,能否只传第一个参数 如何实现,前提这个类不能继承后重写方法,因为多人合同写的. 解决方案 不可以,变通的办法是再写一个只有一个参数的函数重载形式,在其中给另一个参数一个预设值,间接调用. 解决方案二: 一个Action调用两个不同的方法 解决方案三: 调用的时候给一个无影响的值 解决方案四: 讲道理的话是不能这样做的,不过如果

socket通信-用vc写一个socket程序 实现两个客户端通过一个服务器的对话

问题描述 用vc写一个socket程序 实现两个客户端通过一个服务器的对话 初学socket 求详细教程,最好有C++源码 感激不尽 解决方案 孙鑫的VC视频教程中就有这样的例子程序,可以参考一下.

结构体-要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 区分头尾指针相等的情况

问题描述 要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 区分头尾指针相等的情况 我这个算法不知道为什么不能初始化,可能犯了很蠢的错误,求大神解答!!! /*循环队列_使用tag表示空或满_Solo*/ #include <stdio.h> #define MAXSIZE 50 #define FALSE 0 #define TRUE 1 typedef char CSQueueElemType; typedef struct { CSQueueElemType ele

javascript-js点击某一个链接交替执行两个函数(js实现网页全屏问题)

问题描述 js点击某一个链接交替执行两个函数(js实现网页全屏问题) 想实现的需求:1.网页上有个"全屏显示"按钮(链接),点击全屏后执行函数fullScreen(),然后"显示全屏"二字变成"退出全屏":2.点击"退出全屏"执行函数exitFullScreen(),然后"退出全屏"变为"全屏显示" function fullScreen() { var el = document.do