STL源码剖析——序列式容器#4 Stack & Queue
Stack
stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口,元素的新增、删除、最顶端访问都在该出口进行,没有其他位置和方法可以存取stack的元素。换言之,stack不允许有遍历行为。
在学习了deque之后,我们知道了deque是一个双向开口的结构,deque的首尾端都能进行元素的插入和删除。我们既然拥有了这样的一个结构,那只要稍加调整就能符合stack的特征了,不必再另起炉灶。若以deque为底部机构并封闭其前端开口,保留尾端开口,便轻而易举地形成了一个stack。因此,SGI STL便以deque作为缺省情况下的stack底部结构,stack的实现因而非常简单,源码十分简短。
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = deque<T> >
#else
template <class T, class Sequence>
#endif
class stack {
//以下 __STL_NULL_TMPL_ARGS会展开为<>,是来自别处的typedef
friend bool operator== __STL_NULL_TMPL_ARGS(const stack&, const stack&);
friend bool operator< __STL_NULL_TMPL_ARGS(const stack&, const stack&);
public:
//与deque别无二致的相应类型
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; // 底层容器,缺省为deque<T>
public:
// 以下完全利用 Sequence c 的操作,完成 stack 的操作。
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(); }
// deque 是两头可进出,stack 是末端进,末端出(所以后进者先出)。
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
}; 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;
} __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */
另注,stack没有迭代器,因为stack的所有元素必须符合“先进后出”的条件,只有stack最顶端的元素,才有被机会访问或弹出。所以stack不提供遍历功能,也不提供迭代器。
Queue
与之相反,有先进后出的数据结构,肯定也会有先进先出的数据结构,queue就是一种先进先出的数据结构。它有一个入口、一个出口,允许从最底端加入元素,从最顶端弹出元素,除了这两个存取操作外,没有任何其他方法可以存取queue的其他元素。同样,它不允许有遍历行为。
我们只要取deque的部分功能便可实现queue的全部。所以queue的实现非常简单,源码十分简短:
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = deque<T> >
#else
template <class T, class Sequence>
#endif
class queue {
friend bool operator== __STL_NULL_TMPL_ARGS(const queue& x, const queue& y);
friend bool operator< __STL_NULL_TMPL_ARGS(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:
// 以下完全利用 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 是末端进,前端出(所以先进先出)。
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
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;
}
同样,queue不提供迭代器。
STL源码剖析——序列式容器#4 Stack & Queue的更多相关文章
- STL源码剖析——序列式容器#1 Vector
在学完了Allocator.Iterator和Traits编程之后,我们终于可以进入STL的容器内部一探究竟了.STL的容器分为序列式容器和关联式容器,何为序列式容器呢?就是容器内的元素是可序的,但未 ...
- STL源码剖析——序列式容器#2 List
list就是链表的实现,链表是什么,我就不再解释了.list的好处就是每次插入或删除一个元素,都是常数的时空复杂度.但遍历或访问就需要O(n)的时间. List本身其实不难理解,难点在于某些功能函数的 ...
- STL源码剖析——序列式容器#5 heap
准确来讲,heap并不属于STL容器,但它是其中一个容器priority queue必不可少的一部分.顾名思义,priority queue就是优先级队列,允许用户以任何次序将任何元素加入容器内,但取 ...
- STL源码剖析——序列式容器#3 Deque
Deque是一种双向开口的连续线性空间.所谓的双向开口,就是能在头尾两端分别做元素的插入和删除,而且是在常数的时间内完成.虽然Vector也可以在首端进行元素的插入和删除(利用insert和erase ...
- STL源码剖析:算法
启 算法,问题之解法也 算法好坏的衡量标准:时间和空间,单位是对数.一次.二次.三次等 算法中处理的数据,输入方式都是左闭又开,类型就迭代器, 如:[first, last) STL中提供了很多算法, ...
- STL源码剖析之序列式容器
最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
随机推荐
- 如何查看WinDbg扩展有哪些命令
如果您想查看任何windbg扩展所支持的命令,可以采用各种方法. 你可以用!<ext_name>.help命令查看该扩展支持的所有命令.用扩展模块名替换<ext_name>.( ...
- 埃氏筛优化(速度堪比欧拉筛) + 洛谷 P3383 线性筛素数 题解
我们一般写的埃氏筛消耗的时间都是欧拉筛的三倍,但是欧拉筛并不好想(对于我这种蒟蒻) 虽然 -- 我 -- 也可以背过模板,但是写个不会的欧拉筛不如写个简单易懂的埃氏筛 于是就有了优化 这个优化还是比较 ...
- 「SDOI2014」旅行(信息学奥赛一本通 1564)(洛谷 3313)
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我 ...
- shell 命令行参数(基本)
命令行参数 $0 表示程序名.$1 至 \$9则是位置参数.$# 表示参数的个数.$* 将所有参数当做一个整体来引用$@ 把每个参数作为一个字符串返回,可以使用for循环来遍历$? 最近一个执行的命令 ...
- 【Beta】Phylab 发布说明
Phylab Beta阶段发布说明 一.发布地址 Phylab 二.新功能 1. Markdown(Html)报告生成 在生成报告界面可以选择报告生成方式:Latex或Markdown模板.目前支持M ...
- CloudFlare上线了新的Proxy Anything选项, 支持转发TCP连接
https://www.nicho1as.wang/articles/cf-proxy-anything.html 申请地址:https://goo.gl/forms/Oc2jyyo0kXsrMyw3 ...
- Understanding Variational Autoencoders (VAEs)
Understanding Variational Autoencoders (VAEs) 2019-09-29 11:33:18 This blog is from: https://towards ...
- 微信小程序公共方法创建与调用
在根节点建个 utils 文件夹,在文件夹下建立 util.js 在util.js里面写入 var util = {}; util.getUserId= function(e, t) { ...
- numpy的文件存储.npy .npz 文件详解
Numpy能够读写磁盘上的文本数据或二进制数据. 将数组以二进制格式保存到磁盘 np.load和np.save是读写磁盘数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 ...
- dubbo连接过程
场景1 启动时 dubbo服务提供端在Zookeeper上注册的节点目录:假设接口名称是:com.bob.dubbo.service.CityDubboService dubbo服务提供端连接到注册中 ...