1. 程式人生 > >棧和佇列的面試題(四)---用兩個棧實現一個佇列

棧和佇列的面試題(四)---用兩個棧實現一個佇列

一:前面講了用兩個佇列實現一個棧;接下來就是使用兩個棧實現一個佇列 了;
其實說白了;棧和佇列的相互實現,就是利用一個的特點實現另一個的特點;
使用兩個棧實現一個佇列,即就是用兩個“先進後出”的棧實現一個“先進先出”的佇列。而且佇列可以取隊頭的元素,就是第一個進去的元素;而棧只能取棧頂的元素,也就是最後一個元素;

①進行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;
}

四:執行結果
這裡寫圖片描述

☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺