5. 用兩個隊列實現一個棧

  • 壓棧操做直接用隊列的enqueue操做模擬。這道題的難點在於如何模擬出棧操做。html

    隊列中的元素只有在成爲隊頭後纔有資格被dequeue操做刪掉,那麼這道題實際上是在問,如何把一個隊列的隊尾移動到隊頭位置,刪除它以後,其餘元素能夠按原順序放回?把隊列A的元素依次出隊,並送入隊列B,直到隊列A中只剩下一個元素,它既是隊尾又是隊頭,把它出隊後,在反過來把隊列B中元素依次出隊,並送回隊列A。這即是把隊列A隊尾元素刪掉的過程。數組

#include "queue.h"
template<typename Object>
class StackByQueues
{
public:
    StackByQueues()
    {
        for(int i = 0; i != NUM; ++i)
            pQueue[i] = new Queue<Object>;
    }

    StackByQueues(const StackByQueues& rhs)
    {
        for(int i = 0; i != NUM; ++i)
            pQueue[i] = new Queue<Object>(*(rhs.pQueue[i]));
    }
    StackByQueues(StackByQueues&& rhs)
    {
        for(int i = 0; i != NUM; ++i)
        {
            pQueue[i] = rhs.pQueue[i];
            rhs.pQueue[i] = nullptr;
        }
    }
    StackByQueues& operator =(const StackByQueues& rhs)
    {
        auto copy(rhs);
        for(int i = 0; i != NUM; ++i)
            std::swap(this->pQueue[i], copy.pQueue[i]);
        return *this;
    }
    StackByQueues& operator =(StackByQueues&& rhs)
    {
        for(int i = 0; i != NUM; ++i)
            std::swap(this->pQueue[i], rhs.pQueue[i]);
        return *this;
    }
    ~StackByQueues()
    {
        for(int i = 0; i != NUM; ++i)
        {
            if(pQueue[i])
                delete pQueue[i];    //注意:這裏不能寫成 delete pQueue;
        }
    }
    void push(const Object& object)
    {
        if(pQueue[0]->full())
            std::cout << "overflow" << std::endl;
        else
            pQueue[0]->enqueue(object);
    }
    void push(Object&& object)
    {
        if(pQueue[0]->full())
            std::cout << "overflow" << std::endl;
        else
            pQueue[0]->enqueue(std::move(object));
    }
    Object top()
    {
        if(pQueue[0]->empty())
        {
            std::cout << "underflow" << std::endl;
            return Object();
        }
        else
        {
            return pQueue[0]->tail();
        }
    }
    void pop()
    {
        if(pQueue[0]->empty())
            return;
        auto size = pQueue[0]->getSize();    //注意:寫循環語句時要注意,條件變量值是否會被循環體修改,例如這裏的getSize()
        for(int i = 0; i != size-1; ++i)
            pQueue[1]->enqueue(pQueue[0]->dequeue());

        pQueue[0]->dequeue();

        size = pQueue[1]->getSize();
        for(int i = 0; i != size; ++i)
            pQueue[0]->enqueue(pQueue[1]->dequeue());
    }

    bool empty() const{return pQueue[0]->empty();}
    bool full() const {return pQueue[0]->full();}
private:
    static constexpr int NUM = 2;
    Queue<Object>* pQueue[NUM];
};

void testStackByQueues()
{
    using namespace std;
    struct Student
    {
        char name[10];
        int  age;
    };
    constexpr int NUM = 5;
    Student students[NUM] = {Student{"Tom", 12},Student{"Micheal", 13},
                          Student{"Anna", 14},Student{"Lily", 10},
                          Student{"James", 19}};
    StackByQueues<Student> s;
    for(int i = 0; !s.full() && i != NUM; ++i)
        s.push(students[i]);

    decltype(s) s_copy(s);
    decltype(s_copy) s_move(std::move(s_copy));

    while(!s_move.empty())
    {
        auto stu = s_move.top();
        s_move.pop();
        cout << "name: " << stu.name << " age: " << stu.age << endl;
    }
}

/*test output:
name: Lily age: 10
name: Anna age: 14
name: Micheal age: 13
name: Tom age: 12
*/

隨筆《棧和隊列的數組實現》給出了queue.h的實現this

相關文章
相關標籤/搜索