STL(七):stack 與 queue
阿新 • • 發佈:2019-02-17
好久沒有寫過新的內容了。主要是最近真的沒有時間。
好吧,這次介紹一下棧與佇列的內容。
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 類的。