SGI STL队列queue
queue简介
队列queue是一种先进先出(FIFO)的数据结构。有2个出口:允许从头部移除、查询元素,从尾部加入元素。除此之外,无法存取其他位置元素,也不允许遍历。
将元素推入queue的操作称为push,将元素推出queue的从中称为pop。
queue的数据结构
类似于stack,queue也是依赖于底层容器实现其操作,以满足FIFO特性。queue往往被称为container adapter,而不称为container。SGI STL中,queue默认底层容器是deque。
# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp
// stack底层容器默认是deque
template <class _Tp,
class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >
class queue {
// __STD_QUALIFIER展开为std::, __STL_NULL_TMPL_ARGS展开为<>
friend bool __STD_QUALIFIER
operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&);
friend bool __STD_QUALIFIER
operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&);
public:
// 定义内嵌类型
typedef typename _Sequence::value_type value_type;
typedef typename _Sequence::size_type size_type;
typedef _Sequence container_type;
typedef typename _Sequence::reference reference;
typedef typename _Sequence::const_reference const_reference;
protected:
_Sequence c; // 底层容器
public:
queue() : c() {}
explicit queue(const _Sequence& __c) : c(__c) {}
// 以下利用Sequence c的操作, 完成queue的操作
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(); }
reference back() { return c.back(); }
const_reference back() const { return c.back(); }
// deque 双端可进出, queue只支持尾端进, 首端出, 以支持FIFO
void push(const value_type& __x) { c.push_back(__x); }
void pop() { c.pop_front(); }
};
// 比较两个queue x, y的所有元素是否相等
template <class _Tp, class _Sequence>
bool
operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
{
return __x.c == __y.c;
}
// 比较queue x是否小于stack y
template <class _Tp, class _Sequence>
bool
operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
{
return __x.c < __y.c;
}
queue没有迭代器
queue所有元素必须符合“先进先出”的规则,只有队头元素才能被外界访问,只有队尾才能插入数据。queue不提供遍历功能,也不提供迭代器。
以list作为queue底层容器
除了deque,list也是双向开口的容器,也能作为queue的底层容器。queue要求底层容器支持empty(),size(),back(),push_back(),pop_back()等接口。
以list作为queue底层容器示例:
int main()
{
queue<int, list<int>> iqueue;
iqueue.push(1);
iqueue.push(3);
iqueue.push(5);
iqueue.push(7);
cout << iqueue.size() << endl; // 4
cout << iqueue.front() << endl; // 1
iqueue.pop(); cout << iqueue.front() << endl; // 3
iqueue.pop(); cout << iqueue.front() << endl; // 5
iqueue.pop(); cout << iqueue.front() << endl; // 7
cout << iqueue.size() << endl; // 1
return 0;
}