两个栈实现一个队列&两个队列实现一个栈

来源:互联网 发布:商场女装品牌推荐 知乎 编辑:程序博客网 时间:2024/04/20 08:45

Hello,今天Val来给大家分享关于利用 栈实现队列 和 利用队列来实现栈。

准备知识

1、栈 特点: 栈顶插入数据,栈顶删除数据
LIFO(last in first out)后进先出
2、队列 特点: 队列队头删除数据,队尾插入数据
FIFO(first in first out)先进先出

一、那么如何利用两个栈实现一个队列?
我们知道不管是在队列中插入数据,还是删除数据,它都有它的规则,不管我们底层怎样去实现它,都必须保证它的规则不发生改变,我们需要了解队列(queue)的接口。
基本有插入和删除操作,取队头数据,队列的大小,是否为空等。
两个栈实现一个队列:创建一个StoQS类,在类里面实现插入、删除等的接口,类里面有两个栈,一个栈存放数据,另一个栈用来辅助实现队列。

Push插入:队列插入和栈的插入一样,所以直接在类里面写函数内部利用栈的插入函数即可;
Pop删除:队列删除数据是头删(注意删除数据前要判断里面是否还有数据),如果有数据,删除内部栈的栈底数据,此时需要辅助栈来辅助实现这个功能。

二、两栈 To 队列 思想过程
1、stack 是一个容器适配器(container),它在C++库里面有构造函数(constructor()),栈的尺寸大小函数(size()),返回栈顶数据(top())
,插入(push()),删除栈顶元素(pop());

(1)还有在C++11里才有的函数swap(),它的作用是交换两个栈的数据;在两栈实现队列的Pop()功能时,我用了两个栈,先把第一个放到第二个中去,当第一个中元素剩下一个时,就相当于是队列的第一个元素了,记录它,(如果栈2非空)再把栈2中的元素放回栈1,始终以栈1为基础栈,栈2做辅助栈。

最后当我想起来栈有swap()接口时,嗯,用swap应该比较方便,当我为了拿到栈1栈底数据时,把栈1中的数据放到栈2中,当栈1剩一个元素时,删掉它,然后如果栈2非空,栈1和栈2交换即可。 同理,我在实现Front()函数时也用到了swap()函数。 如果要用swap()函数,记住一定要注意你的编译环境,C++11,是2011年出来的,如果你的编译器在11年以前,那就不能使用这个函数。那就老老实实把数据从栈2放到栈1里面去。

(2)还有一个函数emplace(),也是C++11里面的函数,这里我只是简单介绍一下它,emplace(),构造和插入元素,在顶部添加一个新的元素,新元素被构造成args,作为构造函数的参数,比如:我有一个栈s1,栈里有没有元素现在不关注,我知道这个栈里面元素类型,现在我想往里面插入一个元素,假设它是int型的,那么我要插入一个8,就可以这样写:s1.emplace(8);之后再看栈里面的数据栈顶多了一个8,栈的大小size()比原来增加了1。

二、代码实现StoQ

现在我相信,经过看来上面的详细介绍,你们心里应该有一点feel了吧,下面呈上我的代码:

#pragma once#include <iostream>#include <stack>using namespace std;template<class T>class SToQ{public:    void Push(T aim)    {        s1.push(aim);    }    //队列出数据只会从队头出,所以删除的是最先插入的那个    void Pop()    {        if (s1.empty())        {            return;        }        while (!s1.empty())        {            if (s1.size() == 1)            {                s1.pop();                break;            }            else            {                T out = s1.top();                s1.pop();                s2.push(out);            }        }        if (s1.empty() && s2.empty())        {            cout << "NO data now..\n" << endl;            return;         }        while (!s2.empty())        {            /*T in = s2.top();            s2.pop();            s1.push(in);*/            s1.swap(s2);//C++11里也可以这样做,直接交换        }        return;    }    T Front()    {        if (s1.empty())        {            return NULL;        }        else        {            T front = 0;//记录队头数据            while (!s1.empty())            {                if (s1.size() == 1)                {                    front = s1.top();                }                T out = s1.top();                s1.pop();                s2.push(out);            }            while (!s2.empty())            {                /*T in = s2.top();                s2.pop();                s1.push(in);*/                s1.swap(s2);//交换栈1和栈2数据            }            return front;        }    }   T Back()//队列的队尾数据    {        return s1.top();    }    size_t Size()    {        return s1.size();    }protected:    stack<T> s1;    stack<T> s2;};

三、两个队列实现一个栈 QtoS

先说一下我在写这个函数时绕的一个大圈,栈不是有个函数是top (),取栈顶数据,我绕了地球3圈才拿到了它,O__O “… ,说一说这个智障的想法,千万不要学我,我当时想队列只能头删,我把队列1的数据删到队列只有一个数据时,把它记录下来,删的过程中,每pop一个,把它放到队列2中去,再把队列2数据放回队列1,怎么样,服不服气?是不是很傻??

直到我浏览cplusplus网站,原来队列有个接口back()呀,返回的就是队尾数据,这样如果调用这个函数实现栈的top()功能就很方便嘛,一行代码的事儿~

所以一定要多读书,尽管我们长得很好看,也要多读书~

好了上代码:

template<class T>class QtoS{public:    //函数调用接口    void Push(T aim)//模拟在栈里放数据    {        q1.push(aim);    }    void Pop()//模拟在栈里删除数据  边界情况    {            while (!q1.empty())            {                if (q1.size() == 1)                {                    q1.pop();                    break;                }                else                {                    T qout = q1.front();                    q1.pop();                    q2.push(qout);                }            }        if (q1.empty() && q2.empty())        {            cout << "No data for you deleting~\n";            return;        }        while (!q2.empty())        {            /*T qin = q2.front();            q2.pop();            q1.push(qin);*/            q1.swap(q2);        }        return;    }    bool Empty()    {        return q1.empty();    }    size_t Size()    {        return q1.size();    }    T Top()    {        if (q1.size())        {            T tp = q1.back();            return tp;        }    }protected:    queue<T>q1;//q1为主要的q2辅助实现    queue<T>q2;};

今天Val关于栈和队列相互实现的分享就到这里啦~
Have a nice day,bye!

原创粉丝点击