1. 程式人生 > >STL(七):stack 與 queue

STL(七):stack 與 queue

好久沒有寫過新的內容了。主要是最近真的沒有時間。

好吧,這次介紹一下棧與佇列的內容。

stack

先理一下之前寫過的容器:

  • vector
  • deque
  • list

這些都是序列式容器,但是使用了不同的資料結構來實現。

棧的特性,就是先進後出(或者後進先出)
一般來說,我們可以使用上面的容器來實現棧。

事實上,當你看到STL 中的設計時,才感嘆,真是一種絕美的設計啊。

這次先從程式碼說起,它的全部程式碼都如下:


template<class T, class Sequence = deque<T> >
class stack
{
    friend
bool operator == (const stack& x, const stack& y); friend bool operator < (const stack& x, const stack& y); public: typedef typename Sequence::value_type value_type; typedef typename Sequence::size_type size_type; typedef typename Sequence::reference reference; typedef
typename Sequence::const_reference const_reference; protected: Sequence c;//container public: bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference top() { return c.back(); } const_reference top() const { return c.back(); } void push(const
value_type& x) { c.push_back(x); } void pop() { c.pop_back(); } void swap(stack& x) { c.swap(x.c); } }; template<class T, class Sequence> bool operator == ( const stack<T, Sequence>& x, const stack<T, Sequence>& y) { return x.c == y.c; } template<class T, class Sequence> bool operator < (const stack<T, Sequence>& x, const stack<T, Sequence>& y) { return x.c < y.c; } template<class T, class Sequence> void swap(stack<T, Sequence>& x, sta ck<T, Sequence>& y) { x.swap(y。。 ; }

程式碼並不長。
stack 接受兩個模板引數,一個是元素的型別,另一個是底層實現的容器。

看命名,其實我們就能夠知道,它接受一個序列式容器。
這個序列式容器,在承諾上應該提供以下介面

  • push_back
  • back
  • size
  • empty
  • pop_back

看到這裡,也許你就能明白為什麼vector 的push 介面非得帶個back 了。

一個規範的介面命名真的太重要了。

廢話有點多,下面說說queue。

queue

其實這個也是一個用底層容器來實現主要功能的類。
佇列的規則是 先進先出(或者後進後出)

序列式容器中的 deque 就很適合這個實現。

所以,它的程式碼如下:


template<class T, class Sequence = deque<T> >
class queue
{
    friend bool operator == (const queue& x, const queue& y);
    friend bool operator < (const queue& x, const queue& y);

public:
    typedef typename Sequence::value_type value_type;
    typedef typename Sequence::size_type size_type;
    typedef typename Sequence::reference reference;
    typedef typename Sequence::const_reference const_reference;


protected:
    Sequence c;

public:
    bool empty() const { return c.empty(); }
    size_type size() const { return c.size(); }
    reference front()  { return c.front(); }
    const_reference front() const { return c.front(); }
    void push(const value_type& x)
    {
        c.push_back(x);
    }
    void pop()
    {
        c.pop_front();
    }

    void swap(queue& x)
    {
        c.swap(x.c);
    }
};

template<class T, class Sequence>
bool  operator == (const queue<T, Sequence>& x, const queue<T, Sequence>& y)
{
    return x.c == y.c;
}

template<class T, class Sequence>
bool operator < (const queue<T, Sequence>& x, const queue<T, Sequence>& y)
{
    return x.c < y.c;
}

template<class T, class Sequence>
void swap(queue<T, Sequence>& x, queue<T, Sequence>& y)
{
    x.swap(y);
}

也是很簡單的一種實現。
過目就好。

它們沒有迭代器

像是stack 和 queue 這種修改底層類的介面,從而達到自己類想要的功能,稱之為配接器(adapter)

所以,它們是沒有迭代器的概念的。

如果開心的話,你也可以實現一個類,按照規定,提供介面給它們,你就可以設計成自己的stack 和 queue 類的。