开始
再开始开始实现之前,首先将定读者已经理解了栈和队列的区别(如果不理解的话,可以先看看这一篇,传送门:【算法】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>