如何用两个栈视线一个队列

开始

再开始开始实现之前,首先将定读者已经理解了栈和队列的区别(如果不理解的话,可以先看看这一篇,传送门:【算法】7 分不清栈和队列?一张图给你完整体会

用两个栈实现一个队列

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

<code class="hljs cpp has-numbering"><span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> <span class="hljs-keyword">class</span> CQueue{
<span class="hljs-keyword">public</span>:
    CQueue(<span class="hljs-keyword">void</span>);
    ~CQueue(<span class="hljs-keyword">void</span>);

    <span class="hljs-keyword">void</span> appendTail(<span class="hljs-keyword">const</span> T& node);
    T deleteHead();

<span class="hljs-keyword">private</span>:
    <span class="hljs-stl_container"><span class="hljs-built_in">stack</span><T></span> stack1;
    <span class="hljs-stl_container"><span class="hljs-built_in">stack</span><T></span> stack2;
};</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>

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

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

这里写图片描述

  • 插入 a b c :往stack1中依次压入了 a b c

  • 删除队列头:将c,b依次从stack1弹出和压入stack2

  • 删除队列头:将b从stack2中弹出

  • 插入d:往stack1中压入d

  • 删除队列头:将c从stack2中弹出

<code class="hljs r has-numbering">template <typename <span class="hljs-literal">T</span>> void CQueue<<span class="hljs-literal">T</span>>::appendTail(const <span class="hljs-literal">T</span>& element){
    stack1.push(element);
}

template <typename <span class="hljs-literal">T</span>> <span class="hljs-literal">T</span> CQueue<<span class="hljs-literal">T</span>>::deleteHead(){
    <span class="hljs-keyword">if</span>(stack2.size() <= <span class="hljs-number">0</span>){
        <span class="hljs-keyword">while</span>(stack1.size > <span class="hljs-number">0</span>){
            <span class="hljs-literal">T</span>& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    <span class="hljs-keyword">if</span>(stack2.size() == <span class="hljs-number">0</span>){
        throw new exceptions(<span class="hljs-string">"queue is empty"</span>);
    }

    <span class="hljs-literal">T</span> head = stack2.top();
    stack2.pop();

    <span class="hljs-keyword">return</span> head;
}</code><ul style="display: block;" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul>

用两个队列实现一个栈

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

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

这里写图片描述

  • 插入a:向queue1中压入a

  • 插入b:向queue1中压入b之前,先将a压入到queue2中,再将a从queue1中弹出

  • 插入c,d:同上过程,最后如图所示

  • 从栈顶删除d:将queue1中的d弹出

  • 从栈顶删除c:queue1为空,此时先将a和b依次压入queue1,再从queue2中弹出

  • 从栈顶删除c:将queue2中的c弹出,并将queue1中的a和b弹出再压入queue2

<code class="hljs cpp has-numbering"><span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> <span class="hljs-keyword">class</span> CStack {    
<span class="hljs-keyword">public</span>:
    CStack(<span class="hljs-keyword">void</span>);
    ~CStack(<span class="hljs-keyword">void</span>);

    <span class="hljs-keyword">void</span> appendTail(<span class="hljs-keyword">const</span> T& node);
    T deleteHead();

<span class="hljs-keyword">private</span>:
    <span class="hljs-stl_container"><span class="hljs-built_in">queue</span><T></span> queue1;
    <span class="hljs-stl_container"><span class="hljs-built_in">queue</span><T></span> queue2;
};

<span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> CStack<T>::CStack(<span class="hljs-keyword">void</span>) {

}

<span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> CStack<T>::~CStack(<span class="hljs-keyword">void</span>) {

}

<span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> <span class="hljs-keyword">void</span> CStack<T>::appendTail(<span class="hljs-keyword">const</span> T& element) {
    <span class="hljs-keyword">if</span> (queue1.size() >= <span class="hljs-number">1</span>) {
        T& data = queue1.front();
        queue1.pop();
        queue2.push(data);
    }
    queue1.push(element);
}

<span class="hljs-keyword">template</span> <<span class="hljs-keyword">typename</span> T> T CStack<T>::deleteHead() {
    T head;
    <span class="hljs-keyword">if</span> (queue1.size() >= <span class="hljs-number">1</span>) {
        head = queue1.front();
        queue1.pop();
    }
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (queue1.size() == <span class="hljs-number">0</span>&&queue2.size() > <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">while</span> (queue2.size() > <span class="hljs-number">1</span>) {
            T& data = queue2.front();
            queue2.pop();
            queue1.push(data);
        }
        head = queue2.front();
        queue2.pop();
        <span class="hljs-keyword">while</span> (queue1.size() > <span class="hljs-number">0</span>) {
            T& data = queue1.front();
            queue1.pop();
            queue2.push(data);
        }
    }
    <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> exception(<span class="hljs-string">"stack is empty"</span>);
    }
    <span class="hljs-keyword">return</span> head;
}</code>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值