七、STL标准模板库大局观
Author: XFFer_
先分享一本 《C++ 标准库 第二版》 ,望在STL的道路上从入门到放弃!(开玩笑的啦,愈行愈远~)
链接: https://pan.baidu.com/s/1nna7m5F11poNNvEi2ydOyQ
提取码: otld
文章目录
01 STL总述、发展史、组成,数据结构谈
1 几个概念
2 推荐书籍
3 算法和数据结构浅谈
4 STL发展史和各个版本
5 标准库的使用说明
6 STL的组成部分
几个概念
- C++标准库:C++ Standard Library
- 标准模板库:Standard Template Library(STL)
- 泛型编程:Generic Programming
推荐书籍
《STL源码剖析》
链接: https://pan.baidu.com/s/1apswforzS6dp5-3S05SKeA
提取码: gk0l
《C++标准库》
链接: https://pan.baidu.com/s/1nna7m5F11poNNvEi2ydOyQ
提取码: otld
STL发展史和各个版本
- HP STL: 惠普STL,是所有STL实现版本的始祖
- SGI STL: 参考惠普STL实现的,Linux下的GNU C++(gccc, g++)使用
- P.J.Plauger STL: Visual C++使用
STL的组成部分
- 容器: vector、list、map
- 迭代器: 用于遍历或者访问容器中的元素
- 算法: (函数),用来实现一些功能,search、sort、copy…
- 分配器
- 其他: 适配器、仿函数等
02 容器分类、array、vector容器精解
1 容器的分类
2 容器的说明
array
vector
容器的分类
-
顺序容器(Sequence Container):能控制插入位置
array
vector
deque
list
forward_list
-
关联容器(Associative Container):元素是 “键值对”,适合用来查找。能够控制插入内容,但不能控制插入位置
set
multiset
map
multimap
-
无序容器(Unordered Container):C++11推出,元素位置不重要,重要的是否存在该元素
unordered_set
unordered_multiset
unordered_map
unordered_multimap
容器的说明
array
内存空间是连续的,大小是固定的
使用形式: array<type_name, N> value_name
可以就当做数组来用。
vector
vector有一个“空间”的概念,容器内存是紧挨着的,故vector从末尾添加元素push_back
时,如果容器空间不足就会重新寻找一个足够大的内存存放对象。
容器中有多少个元素可以用size()
来看,有多少空间可以用capacity()
, c a p a c i t y ≥ s i z e capacity\geq size capacity≥size。
vector基础知识在前面的章节有所提到。
当erase(iter)
容器内部一个元素时,处理是比较高效的,其后的元素地址都会顺次移动,仍然是连续的内存。
当insert(iter, value)
插入一个元素时,代价很大,会造成其后的元素重新构造,导致降低效率。
故可以使用reserve(size)
提前留出空间capacity,可以大量提高程序的预留效率。
03 容器的说明和简单应用例续
1 deque和stack
2 queue
3 list
4 其他forward_list
set/map
unordered_set、unordered_multiset等
deque和stack
deque
:双端数列(double-ended queue) ,分段连续内存,以分段数组的形式存储。
#include <queue>
deque<type_name> value_name;
value_name.push_front(); //从队列的前面插入
value_name.push_back(); //从队列的后面插入
value_name.pop_front(); //从队列的前面删除
value_name.push_back(); //从队列的前面删除
stack
:堆栈/栈,只有一个开口,后进先出,后进会放在栈顶,先进会压在栈底,不支持从总结插入/删除数据。deque实际上是包含着stack的功能的。
queue
:普通队列 先进先出
list:双向链表
不需要内存是连续的,查找效率不突出,但是在任意位置插入和删除元素非常迅速。
begin()/end()
返回一个起始位置/末端下一个位置的iteratorpush_back()
push_front()
在末端/头部插入元素empty()
判断是否为空resize()
将list长度改为容纳n个元素clear()
清空front()
back()
获取头部/末端元素,不能为空pop_front()
pop_back()
从头部/末端删除一个元素insert()
插入一个或多个元素insert(iter, value)
insert(iter, number_of_v, value)
erase()
删除元素/区间内(用iter)元素
vector
和 list
之间的差别
- vector类似于数组,内存空间是连续的,list双线链表,内存空间并不连续
- vector从中间或者开头插入元素效率比较低;但是list插入元素效率非常高
- vector当内存不足时,会重新找一块内存,对原来的内存对象做析构,再在新的内存重新构造
- vector能够高效的随机存取,而list做不到。vector可以通过迭代器,而list需要沿着链表一个个找,直到找到所需的元素
这里vector的细节知识可以参考C++中list用法详解,本文只是简单的总述STL标准库。
其他
forward_list
:单向链表(受限list)set / map
:关联容器。内部实现的数据结构多为红黑树。这些容器没有push_front/back
的操作,因为内存并不是规律的- 常用操作↓
#include <map>
#include <functional>
#include <string>
map<int, string> mymap;
map<string, function<int(int)>> mymap2; //可以存入函数类型为int(int)的函数
//插入的五种方式
mymap.insert(pair<int, string>(000, "first"));
mymap.insert