溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

用兩個棧實現(xiàn)一個隊列——7

發(fā)布時間:2020-09-15 19:17:11 來源:網(wǎng)絡(luò) 閱讀:323 作者:給我個bit位 欄目:編程語言

   用兩個棧實現(xiàn)一個隊列,并實現(xiàn)兩個函數(shù)appendTail和deleteHead,分別完成在隊列尾部插入結(jié)點和在隊列頭部刪除結(jié)點的功能。

    棧的特點是“先進后出,后進先出”,而隊列的特點是“先進先出,后進后出”,因此可以想到只用一個棧是無法完成的,所以會需要兩個棧,先將輸入的數(shù)據(jù)都依次放入一個棧stack1中,但是先進去的數(shù)據(jù)會被壓在棧底,而棧底的數(shù)據(jù)是需要最先被取出的,可畫圖如下:

用兩個棧實現(xiàn)一個隊列——7

當要完成在隊列頭部刪除結(jié)點這就要用到另外一個棧stack2了,可以將第一個棧stack1的棧頂元素依次取出放進另外的棧stack2中,這樣stack1中的棧底元素就變成了stack2中的棧頂元素,當需要刪除隊列頭部結(jié)點的時候就可以pop出stack2的棧頂元素;

而需要在隊列尾部插入結(jié)點就往stack1中壓入數(shù)據(jù):

用兩個棧實現(xiàn)一個隊列——7

也就是相當于,當stack2不為空的時候,要刪除隊列頭部的結(jié)點就從stack2的棧頂中取出數(shù)據(jù),如果stack2為空的時候就將stack1中的數(shù)據(jù)全部都從棧頂取出依次放入stack2中,然后再取出stack2的棧頂元素;而要在隊列尾部插入結(jié)點的時候就直接往stack1里面push數(shù)據(jù),這并不影響刪除隊列首部的結(jié)點,因為每次push數(shù)據(jù)都往stack1里面放,而當stack2不為空的時候從stack2中pop數(shù)據(jù),二者并不影響;

程序如下:

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

template <class T>
class Queue
{
private:
    vector<T> _stack1;         //定義隊列的成員變量直接使用庫類vector
    vector<T> _stack2;
    
public:
    Queue()        //直接用類的默認構(gòu)造函數(shù),這里會自動調(diào)用庫vector中的構(gòu)造函數(shù)創(chuàng)建兩個棧
    {}  

    //當需要向隊列尾部放數(shù)據(jù)的時候,直接在棧1中push數(shù)據(jù)就可以了
    void appendTail(T data)
    {   
        _stack1.push_back(data);
    }   

    //當要刪除隊列頭部的數(shù)據(jù)的時候
    void deleteHead()
    {   
        //先要判斷棧2中是否有數(shù)據(jù),如果有就直接取出棧頂?shù)脑兀藭r就為隊首的數(shù)據(jù)
        if(!_stack2.empty())
        {
            _stack2.pop_back();
        }
        else//若棧2為空,則需要將棧1中的數(shù)據(jù)調(diào)換到棧2中,以保證先進棧1的數(shù)據(jù)放在棧2的頂部
        {
            while(!_stack1.empty())
            {
                _stack2.push_back(_stack1.back());
                _stack1.pop_back();
            }
            if(!_stack2.empty())
                _stack2.pop_back();
            else
            {
                cout<<"the queue is empty..."<<endl;
                return;
            }   
        }
        cout<<"the new head is "<<_stack2.back()<<endl;
    }
     
 //為了觀察方便,這里定義一個打印隊列的函數(shù),這個函數(shù)其實也就是在完成兩個棧實現(xiàn)隊列的過程   
    void print_queue()
    {
    //這里要注意的是不能直接使用對象的成員變量stack1和stack2,因為這樣會更改對象的數(shù)據(jù),而
    //我們只是需要打印數(shù)據(jù)并不希望更改它,因此可以使用vector庫中的拷貝構(gòu)造函數(shù)再構(gòu)造出
    //兩個臨時棧
        vector<T> tmp1(_stack1);
        vector<T> tmp2(_stack2);

        cout<<"head ";
        if(tmp2.empty())//當棧2為空的時候需要將棧1的數(shù)據(jù)挪到棧2再取出
        {
            while(!tmp1.empty())
            {
                tmp2.push_back(tmp1.back());
                tmp1.pop_back();
            }
            while(!tmp2.empty())
            {
                cout<<tmp2.back()<<" ";
                tmp2.pop_back();
            }
        }
        else
        {
        //當棧2不為空的時候先取出棧2的數(shù)據(jù),然后再將棧1的數(shù)據(jù)放入棧2再取出
            while(!tmp2.empty())
            {
                cout<<tmp2.back()<<" ";
                tmp2.pop_back();
                if(tmp2.empty())
                {
                    while(!tmp1.empty())
                    {
                        tmp2.push_back(tmp1.back());
                        tmp1.pop_back();
                    }
                }
            }
        }
        cout<<"tail"<<endl;
        }
};

int main()
{
    Queue<char> queue;
    queue.appendTail('a');
    queue.appendTail('b');
    queue.appendTail('c');
    queue.appendTail('d');
    queue.appendTail('e');
    queue.print_queue();

    queue.deleteHead();
    queue.deleteHead();
    queue.print_queue();

    queue.appendTail('f');
    queue.appendTail('g');
    queue.appendTail('h');
    queue.print_queue();

    return 0;
}


因為上面的隊類是模板類,因此實現(xiàn)了代碼復(fù)用,隊中的數(shù)據(jù)可以為任意類型;

運行程序:

用兩個棧實現(xiàn)一個隊列——7



《完》

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI