栈和队列的面试题(四)---用两个栈实现一个队列
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;
二:图说
三:代码实现
测试代码:
四:运行结果
☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
其实说白了;栈和队列的相互实现,就是利用一个的特点实现另一个的特点;
使用两个栈实现一个队列,即就是用两个“先进后出”的栈实现一个“先进先出”的队列。而且队列可以取队头的元素,就是第一个进去的元素;而栈只能取栈顶的元素,也就是最后一个元素;
①进行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; }
四:运行结果
☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
相关文章推荐
- 剑指offer面试题java实现之题7:用两个栈模拟一个队列的入队和出队操作
- 【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)
- 栈&队列面试题之之两个栈实现一个队列
- 面试题:用两个队列实现一个栈
- 两个栈实现一个队列——栈和队列面试题(2)
- 经典面试题一:用两个栈实现一个队列
- 面试题7两个栈实现一个队列和两个队列实现一个栈
- C++面试题:两个队列实现一个栈
- 面试题之用两个栈实现一个队列
- 《剑指Offer》面试题:用两个队列实现一个栈
- 数据结构面试题:两个队列实现一个堆栈
- 微软,Google面试题 (18) —— 用两个栈实现一个队列
- 面试题之两个队列实现一个栈
- 剑指offer《面试题7:用两个栈实现队列》及用两个队列实现一个栈
- 《剑指Offer》面试题:用两个栈来实现一个队列
- 面试题7:用两个栈实现队列和用两个队列实现一个栈
- 面试题之两个栈实现一个队列,乘机数组问题
- 面试题:用两个栈实现一个队列
- 一个数组实现两个栈——栈和队列面试题(5)
- 两个队列实现一个栈——栈和队列面试题(3)