棧和佇列的面試題(四)---用兩個棧實現一個佇列
阿新 • • 發佈:2019-02-19
一:前面講了用兩個佇列實現一個棧;接下來就是使用兩個棧實現一個佇列 了;
其實說白了;棧和佇列的相互實現,就是利用一個的特點實現另一個的特點;
使用兩個棧實現一個佇列,即就是用兩個“先進後出”的棧實現一個“先進先出”的佇列。而且佇列可以取隊頭的元素,就是第一個進去的元素;而棧只能取棧頂的元素,也就是最後一個元素;
①進行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;
}
四:執行結果
☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺