传送门
STL源码剖析(侯捷版本) —— 第一章 STL 概论与版本简介
STL源码剖析(侯捷版本) —— 第二章 空間配置器 allocator
STL源码剖析(侯捷版本) —— 第三章 迭代器(Iterators)与Traits编程技巧在C++ STL中的应用
STL源码剖析(侯捷版本) —— 第四章 序列式容器(一)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(二)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(三)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(四)
STL源码剖析(侯捷版本) —— 第四章 序列式容器(五)
文章目录
容器(Container)
容器是 STL 的核心组成部分,用于存储和管理数据,包括序列式容器和关联式容器。这些容器实现了各种数据结构,如 vector
、list
、deque
、set
和 map
等。从实现角度来看,STL 容器通常以 class template 的形式提供,用户可以直接使用或自定义。
1. 数据结构与算法的关系
任何特定的数据结构都是为了实现某种特定的算法。容器选择的好坏直接影响算法的效率。
2. 序列式容器 (Sequential Container)
序列式容器是指容器中的元素按某种逻辑顺序排列,但未必经过排序。这些容器适合存储线性结构数据。以下是序列式容器的主要分类:
3. vector
3.1. 特点
vector
是一个动态数组,其大小可以在运行时动态调整。- 它维护一个连续的线性空间,允许通过普通指针作为迭代器。
- 如果添加新元素时超出当前容量,
vector
会将容量扩展到原来的两倍。
3.2. 内存管理原理
vector
动态增加大小的实现是通过 M_insert_aux
函数来实现的:
- 配置新空间:为
vector
分配一块更大的连续空间。 - 拷贝数据:将原来空间的数据拷贝到新的空间。
- 释放旧空间:释放原有的空间。
需要注意的是,一旦 vector
的容量发生变化,指向原容器的所有迭代器都会失效。
3.3. 主要操作
push_back()
:在末尾插入元素。pop_back()
:删除末尾元素。erase()
:删除某个范围[first, last)
或单个元素。insert()
:在指定位置插入元素。clear()
:清空容器中的所有元素。
4. list
4.1. 特点
list
是一个双向链表,支持前后移动的迭代器(Bidirectional Iterator
)。- 链表的插入和删除操作非常高效。
4.2. 主要操作
push_front()
:在头部插入元素。push_back()
:在尾部插入元素。pop_front()
:移除头部元素。pop_back()
:移除尾部元素。insert()
:在指定位置插入元素。
5. deque
5.1. 特点
deque
是一个双端队列,允许在两端进行高效的插入和删除操作。- 与
vector
不同,deque
使用分段连续空间,动态扩展时会增加新的缓冲区。
5.2. 主要操作
push_front()
:在头部插入元素。push_back()
:在尾部插入元素。pop_front()
:在头部删除元素。pop_back()
:在尾部删除元素。
6. stack
6.1. 特点
stack
是一种先进后出的数据结构,只允许在栈顶进行插入和删除操作。- 默认使用
deque
作为底层容器,也可以使用list
。
6.2. 主要操作
push()
:在栈顶插入元素。pop()
:从栈顶弹出元素。top()
:访问栈顶元素。
7. queue
7.1. 特点
queue
是一种先进先出的数据结构,支持在队尾插入元素,在队首删除元素。- 默认使用
deque
作为底层容器。
7.2. 主要操作
push()
:在队尾插入元素。pop()
:从队首移除元素。front()
:访问队首元素。back()
:访问队尾元素。
8. heap
8.1. 特点
- 堆是一个特殊的树形结构,通常用于实现优先队列。
- STL 提供了最大堆(
max-heap
)作为默认实现。
8.2. 主要操作
push_heap()
:将新元素插入堆中并调整堆结构。pop_heap()
:移除堆顶元素,并将其移动到堆的底部。sort_heap()
:将堆排序。make_heap()
:将现有数据转化为堆。
9. priority_queue
9.1. 特点:
priority_queue
是基于堆的优先队列,它按照元素的优先级顺序排列元素。- 默认使用
vector
作为底层容器。
9.2. 主要操作
top()
:访问优先队列的顶端元素。push()
:在队列中插入新元素,并调整堆结构。pop()
:移除队列中的顶端元素。
10. slist
10.1. 特点
slist
是一个单向链表,迭代器是单向的Forward Iterator
。- 元素插入操作会将新元素插入到指定位置之前。
10.2. 主要操作
push_front()
:在头部插入元素。pop_front()
:从头部移除元素。front()
:访问头部元素。