STL源码剖析之序列式容器

序列式容器内容总结:

在这里插入图片描述

序列式容器重难点:

在这里插入图片描述

vector概述

array是静态空间,一旦配置了就不能改变;要换个大(或小)一点的房子,一切琐细得由客户端自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。 vector是动态空间,随着元素的加,它的内部机制会自行扩充空间以容纳新元素。

vector的迭代器
vector选代器所需要的操作行为,如 operator*, operator->, operator++, operator–, operator, operator-
operator=, operator–=,普通指针天生就具备。 vector支持随机存取,而普通指针正有着这样的能力。所以, vector提供的是 Random Access Iterators

vector的数据结构
vector所采用的数据结构非常简单:线性连续空间。它以两个迭代器 start和 finish分别指向配置得来的连续空间中目前已被使用的范围,并以迭代器end_of_storage指向整块连续空间(含备用空间)的尾端:
template <class T, class Alloc alloc>
class vector
{
protected:
iterator start;//表示目前使用空间的头
iterator finish;//表示目前使用空间的尾
iterator end_of_storage;//表示目前可用空间的尾
}
为了降低空间配置时的速度成本, vector实际配置的大小可能比客户端需求量更大一些,以备将来可能的扩充。这便是容量capacity)的观念。换句话说,一个vector的容量永远大于或等于其大小。

vector元素操作:
头文件 : #include < vector >
定义 : vector< typename > vec; //typename可以是任意的数据结构
vector vec(5); //声明一个vector,并为其赋予5的内存空间
vector vec(5,1); //赋予5的内存空间,并把初值都设为1;
vec = vector(5,1); //重新初始化vec的值;
vec.size(); //返回vector的长度,复杂度为O(1);
vec.clear(); //清空vector的内容,并将内存释放;
vec.push_back(x); //在vector后插入x,插入和删除操作使用均摊复杂度来算,复杂度为O(1),使用时方便且复杂度低,相当推荐;
vec.pop_back(); //删除vector最后一个元素,复杂度为O(1);
vec.begin(); //返回vector的起始地址;
vec.end(); //返回vector的终止地址;
sort( vec.begin(),vec.end() ); //对vector排序;
vec.erase( vec.begin() ); //删除vec的首地址的元素,注意传入的一定要是一个地址,复杂度O(n),不建议使用

list概述

相较于 vector的连续线性空间,1ist就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。因此,1ist对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的元素插入或元素移除,list永远是常数时间。

list节点:list本身和list节点是不同的结构,需要分开设计。

list的迭代器
1ist迭代器必须有能力指向lst的节点,并有能力进行正确的递增、递减、取值、成员存取等操作所谓“ist迭代器正确的递增、递减、取值、成员取用”操作是指,递增时指向下一个节点,递减时指向上一个节点,取值时取的是节点的数据值,成员取用时取用的是节点的成员由于STL list是一个双向链表(double linked–list),选代器必须具备前移、后移的能力,所以1ist提供的是 Bidirectional Iterators
list有一个重要性质:插入操作(insert)和接合操作( splice)都不会造成原有的ist迭代器失效。这在 vector是不成立的,因为vector的插入操作可能造成记忆体重新配置,导致原有的迭代器全部失效。

list的数据结构
SGI list不仅是一个双向链表,而且还是一个环状双向链表。所以它只需要一个指针,便可以完整表现整个链表。

list元素操作:
需添加#include
assign() 给list赋值
back() 返回最后一个元素
begin() 返回指向第一个元素的迭代器
clear() 删除所有元素
empty() 如果list是空的则返回true
end() 返回末尾的迭代器
erase() 删除一个元素
front() 返回第一个元素
get_allocator() 返回list的配置器
insert() 插入一个元素到list中
max_size() 返回list能容纳的最大元素数量
merge() 合并两个list
pop_back() 删除最后一个元素
pop_front() 删除第一个元素
push_back() 在list的末尾添加一个元素
push_front() 在list的头部添加一个元素
rbegin() 返回指向第一个元素的逆向迭代器
remove() 从list删除元素
remove_if() 按指定条件删除元素
rend() 指向list末尾的逆向迭代器
resize() 改变list的大小
reverse() 把list的元素倒转
size() 返回list中的元素个数
sort() 给list排序
splice() 合并两个list
swap() 交换两个list
unique() 删除list中重复的元素

deque概述

vector是单向开口的连续线性空间 deque则是一种双向开口的连续线性空间。所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作。deque和 vector的最大差异,一在于 deque允许于常数时间内对起头端进行元素的插入或移除操作,二在于deque没有所谓容量( capacity)观念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

deque的迭代器
deque是分段连续空间。维持其“整体连续假象的任务,落在了迭代器的operator++和operator—两个运算子身上
deque迭代器应该具备什么结构必须能够指出分段连续空间(亦即缓冲区)在哪里,其次它必须能够判断自己是否已经处于其所在缓冲区的边缘,如果是,一旦前进或后退时就必须跳跃至下一个或上一个缓冲区。

deque元素操作
(1) 构造函数
deque():创建一个空deque
deque(int nSize):创建一个deque,元素个数为nSize
deque(int nSize,const T& t):创建一个deque,元素个数为nSize,且值均为t
deque(const deque &):复制构造函数
(2) 增加函数
void push_front(const T& x):双端队列头部增加一个元素X
void push_back(const T& x):双端队列尾部增加一个元素x
iterator insert(iterator it,const T& x):双端队列中某一元素前增加一个元素x
void insert(iterator it,int n,const T& x):双端队列中某一元素前增加n个相同的元素x
void insert(iterator it,const_iterator first,const_iteratorlast):双端队列中某一元素前插入另一个相同类型向量的[forst,last)间的数据
(3) 删除函数
Iterator erase(iterator it):删除双端队列中的某一个元素
Iterator erase(iterator first,iterator last):删除双端队列中[first,last)中的元素
void pop_front():删除双端队列中最前一个元素
void pop_back():删除双端队列中最后一个元素
void clear():清空双端队列中最后一个元素
(4) 遍历函数
reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回指向向量中最后一个元素下一个元素的指针(不包含在向量中)
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素的前一个元素
(5) 判断函数
bool empty() const:向量是否为空,若true,则向量中无元素
(6) 大小函数
Int size() const:返回向量中元素的个数
int max_size() const:返回最大可允许的双端对了元素数量值
(7) 其他函数
void swap(deque&):交换两个同类型向量的数据
void assign(int n,const T& x):向量中第n个元素的值设置为x

stack概述

stack是一种先进后出(First In Last Out,filo)的数据结构它只有一个出口。 stack允许新增元素、移除元素、取得最顶端元素。但除了最顶端外,没有任何其它方法可以存取 stack的其它元素换言之, stack不允许有遍历行为。将元素推 stack的操作称为push,将元素推出 stack的操作称为pop

queue概述

queue是一种先进先出(First In First Out,FFO)的数据结构。它有两个出口。允许新增元素、移除元素、从最底端加入元素、取得最顶端元素。但除了最底端可以加入最顶端可以取出外,没有任何其它方法可以存取 queue的其它元素。换言之, queue不允许有遍历行为将元素推入 queue的操作称为push,将元素推出 queue的操作称为pop

queue元素操作
C++中队列的头文件为
声明
queue<数据类型> 对象;
基本操作
push(): 向队尾压入一个成员;
pop(): 将队头元素弹出,此函数不返回任何值;
front(): 返回对头元素,但不删除成员;
back() 返回队尾元素,但不删除成员;
empty(): 如果队列为空返回true,否则返回false;
size(): 返回队列长度;

priority_queue概述

它允许加入新元素、移除旧元素、审视元素值等功能。由于这是一个 queue,所以只允许在底端加入元素,并从顶端取出元素,除此之外别无其它存取元素的途径。 Priority queue带有权值观念,其内的元素并非依照被推入的次序排列,而是自动依照元素的权值排列(通常权值以实值表示)。权值最高者,排在最前面缺省情况下 priority_queue系利用一个max-heap完成,后者是一个以 vector表现的 complete binary tree max-heap可以满足 priority_queue所需要的“依权值高低自动递增排序”的特性

slist和1ist的主要差别在于,前者的迭代器属于单向的 Forward Iterator,后者的迭代器属于双向的 Bidirectional Iterator.为此, slist的功能自然也就受到许多限制。不过,单向链表所耗用的空间更小,某些操作更快,不失为另一种选择。
slist和1ist共同具有的一个相同特色是,它们的插入(insert)、移除(erase)、接合( splice)等操作并不会造成原有的迭代器失效。

参考:《STL源码剖析》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值