两个队列实现一个栈的两种方案

来源:互联网 发布:uboot源码下载 编辑:程序博客网 时间:2024/05/16 08:07

我们都知道,队列的特点是“先进先出”,而栈的特点是“先入后出”。

因为栈和队列插入元素的时候都是在尾部进行插入,这个所以插入操作很好解决。而队列是从队头开始删除的,栈是从栈顶删除元素,因此,我们需要考虑怎么将元素进行弹出,解决这个问题有两种方案。

方案一:

我们用一个队列作为主要维护栈的队列,该队列用来插入元素和弹出元素。

插入元素时,将元素直接插入到第一个队列的尾部。

弹出元素时:

(1)将第一个队列的除队尾元素以外的所有元素依次弹出并且插入到第二个队列中

(2)将第一个队列中剩下的那个元素弹出

(3)将第二个队列中的所有元素依次倒回到第一个队列中。

总的来说,弹出元素就是将元素导出,删除,倒回的过程。

这样就实现了将最后一个进入队列中的元素先弹出的目标。

入栈过程如下图:

出栈的过程如图:


方案二:

两个队列共同维护栈的入栈和出栈。

和方案一差不多,只是当删除了栈顶元素时,不需要将第二个队列中的元素倒回到第一个队列里。

出栈时,将不为空的队列中元素(出队尾元素)导出到另一个队列中,删除队尾元素。如下图:

1)入栈时只需判断一下哪个队列不为空,就插入到那个队列中,当两个队列都为空时,插入到哪个队列都可以。如下图:

程序如下:

#pragma once#include<iostream>#include<queue>#include<assert.h>using namespace std;//使用两个队列实现一个栈template<class T>class Stack{public:void Push(const T& d){if (!_Qfirst.empty())_Qfirst.push(d);else_Qsecond.push(d);}void Pop(){if (!_Qfirst.empty()){_Pop(_Qfirst, _Qsecond);}else_Pop(_Qsecond, _Qfirst);}bool Empty(){if (_Qfirst.empty() && _Qsecond.empty()){return true;}elsereturn false;}T& Top(){if (!_Qfirst.empty()){return _Qfirst.back();}elsereturn _Qsecond.back();}size_t Size(){if (!_Qfirst.empty()){return _Qfirst.size();}elsereturn _Qsecond.size();}protected:void _Pop(queue<T>& Q1, queue<T>& Q2){while (Q1.size()>1){T& data = Q1.front();Q2.push(data);Q1.pop();}Q1.pop();}protected:queue<T> _Qfirst;queue<T> _Qsecond;};


0 0