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

  • 《算法導論》10.1-6 用兩個棧實現一個隊列,並分析相關隊列操做的運行時間。html

    把棧頂元素當作隊尾元素,向隊尾插入的操做能夠直接用棧的push來完成,這道題的關鍵是如何實現從隊頭刪除的操做。算法

    相應的,棧底元素就至關於隊頭元素,咱們知道,棧底元素是不能自由進出的,而棧頂元素能夠,若是咱們能夠把待刪除的棧底元素移到棧頂的位置,就能夠把它刪掉了。數組

    如何把棧底元素移到棧頂位置呢?這裏就須要另外一個棧B的幫助了,當咱們把元素從棧A依次彈出,壓入棧B,咱們實際上是完成了一個把棧A逆序排列存入棧B的過程。this

    當把B的棧頂彈出後,再反過來把棧B元素逆序排列存入棧A,獲得的新的棧A正好是咱們想要的原棧A移除棧底以後的結果。spa

#include "stack.h"
template<typename Object>
class QueueByStacks
{
public:
    QueueByStacks()
    {
        for(int i = 0; i != NUM; ++i)
            pStack[i] = new Stack<Object>;
    }
    QueueByStacks(const QueueByStacks& rhs)
    {
        for(int i = 0; i != NUM; ++i)
            pStack[i] = new Stack<Object>(*(rhs.pStack[i]));
    }

    QueueByStacks(QueueByStacks&& rhs)
    {
        for(int i = 0; i != NUM; ++i)
        {
            pStack[i] = rhs.pStack[i];
            rhs.pStack[i] = nullptr;
        }
    }

    QueueByStacks& operator =(const QueueByStacks& rhs)
    {
        QueueByStacks copy(rhs);
        for(int i = 0; i != NUM; ++i)
            std::swap(this->pStack[i], copy.pStack[i]);
        return *this;
    }
    QueueByStacks& operator =(QueueByStacks&& rhs)
    {
        for(int i = 0; i != NUM; ++i)
            std::swap(this->pStack[i], rhs.pStack[i]);
        return *this;
    }
    ~QueueByStacks()
    {
        for(int i = 0; i != NUM; ++i)
        {
            if(pStack[i])
                delete pStack[i];
        }
    }

    void enqueue(const Object& object)    //運行時間爲O(1)
    {
        pStack[0]->push(object);
    }

    void enqueue(Object&& object)
    {
        pStack[0]->push(std::move(object));
    }

    Object dequeue()    //運行時間爲O(n),n爲隊列長度
    {
        while(!pStack[0]->empty())
        {
            Object& object = pStack[0]->top();
            pStack[0]->pop();
            pStack[1]->push(object);
        }
        Object& ret = pStack[1]->top();
        pStack[1]->pop();
        while(!pStack[1]->empty())
        {
            Object& object = pStack[1]->top();
            pStack[1]->pop();
            pStack[0]->push(object);
        }
        return ret;
    }

    bool empty() const  {return pStack[0]->empty();}
    bool full() const   {return pStack[0]->full();}

private:
    static constexpr int NUM = 2;
    Stack<Object>* pStack[NUM];
};

void testQueueByStacks()
{
    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}};
    QueueByStacks<Student> q;
    for(int i = 0; !q.full() && i != NUM; ++i)
        q.enqueue(students[i]);
    for(int i = 0; i != NUM; ++i)
    {
        q.dequeue();
        q.enqueue(std::move(students[i]));
    }
    decltype(q) q_copy (q);
    decltype(q_copy) q_move(std::move(q_copy));
    while(!q_move.empty())
    {
        auto stu = q_move.dequeue();
        cout << "name: " << stu.name << " age: " << stu.age << endl;
    }
}
/*output:
name: Micheal age: 13
name: Anna age: 14
name: Lily age: 10
name: James age: 19
*/

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

相關文章
相關標籤/搜索