數據結構:棧與隊列

棧的原則是後進先出,即插入與刪除元素均在棧頂進行。 (獲取棧頂元素:s.top() )

隊列的原則是先進先出,即插入數據在隊尾進行,刪除數據在隊頭進行。  (獲取隊頭元素:q.front() )

  • 用兩個棧實現一個隊列

思路:用兩個棧,一個棧用來進隊,一個棧用來出隊,當數據進入隊列的時候,我們將其壓入一個棧,當數據出隊的時候,我們將保存在棧內的數據pop出來,將其按照出棧的順序壓入另外一個棧,然後pop棧頂的數據就實現了出隊的操作。當我們進行入隊操作的時候,可以直接將數據壓入第一個棧。

示意圖:

                  

實現流程:

1.stack1用來push數據:將數據push到s1前需要先將s2騰空,即把s2中的數據插入到s1中,保證stack2爲空。

2.stack2用來pop數據:

     當stack1不爲空時,將stack1中的數據全部pop出來,按照出棧的順序壓入stack2中,然後拿到s2的棧頂元素並將其pop即可

     當stack2不爲空時,直接pop stack2的棧頂元素即可。

代碼實現:(注意:兩個棧都爲空的時候是不能進行出隊操作的​​​​​​​)

class MyQueue {
public:
    MyQueue() 
    {}
    ~MyQueue() 
    {}

    //入隊
    void push(int x) {   //設置插入到s1中
        while(!s2.empty())
        {
            s1.push(s2.top());
            s2.pop();
        }
        s1.push(x);
    }
    
    //出隊
    int pop() {
        //注意:s1,s2爲空則return
        if(s1.empty() && s2.empty()) 
            return -1;

        while(!s1.empty())  //將s1中元素插入s2中
        {
            s2.push(s1.top());
            s1.pop();
        }
        int ret = s2.top();   //拿到s2的top
        s2.pop();
        return ret;
    }
    
    //獲取隊頭(即獲取轉移後的棧頂元素)
    int peek() { 
        if(s2.empty())
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
        }
        int ret = s2.top();
        return ret;
    }
    
    //判空
    bool empty() {
        return  s1.empty() && s2.empty();
    }
    
private:
    stack<int> s1;
    stack<int> s2;
};

  • 用兩個隊列實現一個棧

思路:要實現一個棧,那麼後進入的數據一定是先出去的。利用兩個隊列來進行數據順序的調整。當數據進入一個棧時,可以先將數據push到一個隊列當中;當需要刪除數據時,因爲隊列是先進先出的,所以我們可以將隊尾的元素保留下來,其餘元素按照出隊的順序入隊到另外一個隊列當中,然後pop第一個隊列的最後剩下的一個元素,這樣就實現了棧的刪除操作。

示意圖:

               

實現步驟:

1.push數據:在插入數據的時候,需要對隊列進行判斷,將數據插入到非空的隊列當中(都爲空則默認插入q1)。這樣的話pop時我們分情況討論的時候只用分隊列爲空和不爲空兩種情況,有利於代碼的編寫。

2.pop數據:在刪除數據時,我們需要將非空隊列的隊尾數據保存下來最後進行pop,其餘數據入隊到另外一個隊列當中。就這樣利用兩個隊列來對數據進行來回交換實現棧。

代碼實現:(注意:當兩個隊列都爲空的時候是沒有辦法pop數據的

class MyStack {
public:
    MyStack()
    {}
    ~MyStack()
    {}
    
    //入棧
    void push(int x) {     //插入非空隊列(都爲空默認插入q1)
      if(!q2.empty())
        q2.push(x);
      else
        q1.push(x);
        
    }
    
    //出棧
    int pop() {
      if(q1.empty()&&q2.empty())      //都爲空無法pop
        return -1;
      int ret;
      if(!q1.empty())     //q1不爲空,將q1中的size-1個元素插入q2
      {
        while(q1.size()!=1) 
        {
          q2.push(q1.front());
          q1.pop();
        }
        ret = q1.front();  //拿到q1中僅剩的一個元素
        q1.pop();
      }
      else        //q2不爲空,將q2中的size-1個元素插入q1
      {
        while(q2.size()!=1) 
        {
          q1.push(q2.front());
          q2.pop();
        }
        ret = q2.front();   //拿到q2中僅剩的一個元素
        q2.pop();
      }
      return ret;
    }
    
    //獲取棧頂元素
    int top() {    //返回非空隊列的隊尾元素
      if(!q1.empty())
         return q1.back();
      else
        return q2.back();
    
    }
    
    //判空
    bool empty() {
        return q1.empty() && q2.empty();
    }
private:
  queue<int> q1;
  queue<int> q2;
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章