您的位置:首页 > 职场人生

栈和队列的面试题(四)---用两个栈实现一个队列

2017-04-17 00:21 399 查看
一:前面讲了用两个队列实现一个栈;接下来就是使用两个栈实现一个队列 了;

其实说白了;栈和队列的相互实现,就是利用一个的特点实现另一个的特点;

使用两个栈实现一个队列,即就是用两个“先进后出”的栈实现一个“先进先出”的队列。而且队列可以取队头的元素,就是第一个进去的元素;而栈只能取栈顶的元素,也就是最后一个元素;

①进行pop操作(删第一个元素)

定义了两个栈S1和S2,S1为主栈,S2位辅助栈,在删除栈底元素时辅助使用;

当给第一个栈s1 push进元素,第二个栈为空!此时如果要进行队列原则的pop,

即就是把第一个元素 pop掉,显然用一个栈s1时不能实现的,这时将s1的top插入到s2中,只给s1中留第一个元素,然后pop掉!这样就减少了一次push进s2的压栈开销!效率更高

②进行push操作(插入到与原顺序的后面)

push的时候,如果s1中有元素,则直接给s1后面push元素,如果s1中无元素,元素全都在S2中,这时不能直接给s2中直接push元素,这样以前的顺序就乱了,要把s2中的元素先全部取top,然后在给S1后面插入元素。

③返回队列第一个元素

和pop操作基本相同,只是最后剩下的S1中的一个元素,先用一个变量将其保存,然后删除,最后返回该变量;

④返回队列最后一个元素

如果S2不为空,直接返回S2的栈顶元素,此元素就是队列的首元素;

如果S2为空,S1不为空,则先把S1中的元素全都取Top操作,压入S2中,每压进去一个,pop一次S1,直到最后S1中剩下一个元素,先用变量保存,再压入s2,然后pop s1;

二:图说



三:代码实现

#include<iostream>
#include<stack>
using namespace std;

template<typename T>
class Queue
{
public:
void Push(const T& x)//插入元素
{
if (!_s2.empty())//元素全在s2
{
//要把s2中的元素先全部取top,然后在给S1后面插入元素。要不入栈的顺序会乱
while (!_s2.empty())
{
_s1.push(_s2.top());

_s2.pop();
}
}
_s1.push(x);//s1中有元素
}
void Pop()//删除
{
if (!_s2.empty())//s1为空s2不为空
{
_s2.pop();
}
if (!_s1.empty() && _s2.empty())//s2为空,s1不为空
{

while (_s1.size() != 1)//第一个元素留在s1
{
_s2.push(_s1.top());//可以少push一次
_s1.pop();
}
_s1.pop();//删除第一个元素
}
}
T Back()//返回队列最后一个元素
{

if (!_s2.empty())//s1为空s2不为空
{
T tmp=0;
while (!_s2.empty() )//第一个元素留在s1
{
if (_s2.size()==1)
{
tmp=_s2.top();
}
_s1.push(_s2.top());
_s2.pop();
}
return tmp;
}
if (!_s1.empty() && _s2.empty())//s2为空,s1不为空
{
return _s1.top();
}
}
T Front()//返回队列第一个元素
{

if (!_s2.empty())//s1为空s2不为空
{
return _s2.top();
}
if (!_s1.empty() && _s2.empty())//s2为空,s1不为空
{
T tmp=0;
while (!_s1.empty() )//第一个元素留在s1
{
if (_s1.size()==1)
{
tmp=_s1.top();
}
_s2.push(_s1.top());
_s1.pop();
}

return  tmp;
}

}
int Size()//队列元素个数
{
return _s1.size() + _s2.size();
}
public:
stack<T> _s1;
stack<T> _s2;
};


测试代码:

void test()
{
Queue<int> q;
q.Push(1);
q.Push(2);
q.Push(3);
q.Push(4);
q.Push(5);
cout<<"队列大小:"<<q.Size()<<endl;
cout<<"队列首元素:"<<q.Front()<<endl;
cout<<"队列尾元素:"<<q.Back()<<endl;
q.Pop();
q.Pop();
cout<<"队列大小:"<<q.Size()<<endl;
cout<<"队列首元素:"<<q.Front()<<endl;
cout<<"队列尾元素:"<<q.Back()<<endl;

}
int main()
{
test();
system("pause");
return 0;
}


四:运行结果



☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息