文章目录
- 数组
- array
- vector
- 栈和队列
- deque
- stack
- queue
- 堆
- heap
- priority_queue
- 链表
- list
- forward_list
- 树
- set
- map
- multiset
- multimap
- 哈希表
- unordered_set
- unordered_map
- unordered_multiset
- unordered_multimap
- 图
数组
array
不开口的连续线性空间,支持随机访问。
array是C++11中新提出来的容器类型,它继承了数组最基本的特性,同时也融入了很多容器操作,容器化使得array可以严格检查越界读写,因此与C语言数组相比,array更加安全,可以用来替代C语言数组。作为C语言数组的升级版,array和数组一样,是一种固定大小的容器类型,在定义的时候就要声明大小和类型。无法动态的扩展或收缩,只允许访问或者替换存储的元素。
array的数据存储在栈中,因此处理数据的效率快于vector,但是由于需要考虑栈溢出问题,array只适合一些操作简单、数据量较少的情况。
- array支持的操作
vector
单向开口的连续线性空间,支持随机访问。
动态空间,随着新元素的加入,它的内部机制会自行扩充空间以容纳新元素。
扩充空间=配置新空间+数据移动+释放旧空间。
vector维护的是连续线性空间,其指针就是普通指针。
为了降低频繁空间配置带来的成本开销,vector实际配置的大小会比客户需求的更大一些,以备将来可能的扩充。
所谓动态增加大小,并不是在原空间之后接续新空间(因为无法保证原空间之后有可供配置的空间),而是以原空间大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容后边构造新元素,并释放原空间。
因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。
- vector常见操作如下
栈和队列
deque
双向开口的连续线性空间,支持随机访问。
- deque支持的操作
stack
一端开口的连续线性空间,不支持随机访问。
FILO(先进后出)
将deque的头端开口关闭,就形成了一个stack。
- stack支持的操作
queue
头尾两端单向开口的连续线性空间,不支持随机访问。
FIFO(先进先出)
将deque头端的入口和尾端的出口关闭,就形成了一个queue。
- queue支持的操作
堆
heap
一种用数组表述完全二叉树的方式,分为大根堆和小根堆。
heap=vector+heap算法。
heap并非STL的容器组件,而是以算法形式呈现,作为priority_queue的幕后助手。
priority_queue
priority_queue使用vector作为其底层存储数据的容器,在vector上又使用了heap算法将vector中元素构造成堆的结构,因此priority_queue是C++ STL提供的堆容器。
priority_queue是一个queue,所以只允许在底端加入元素,并从顶端取出元素。
其元素并非依照被推入队列的顺序排列。而是自动依照元素的权值排列。默认为大根堆,即权值最高者排在最前面。
- priority_queue支持的操作:
链表
list
list是环状双向链表。
- list常见操作
forward_list
forward_list是单向链表。
- forward_list常见操作
树
二叉搜索树(BST)提供对数时间的元素插入和访问。其节点放置规则是:任何节点的值一定大于其左子树中每一节点的值,并小于其右子树中每一节点的值。故其中序遍历为递增序列。
平衡二叉搜索树要求没有任何一个节点过深,即加了平衡条件的二叉搜索树。包括AVL树和红黑树等。
-
AVL树要求任何节点的左右子树高度相差最多1。
-
红黑树在二叉搜索树的基础上,添加以下规则:
- 节点分为红色和黑色;
- 根节点为黑色;
- 如果节点为红色,则其子节点必须为黑色;
- 任一节点至NULL的任何路径,所含黑色节点数必须相同。
set、map、multiset、multimap均以红黑树为底层结构。
set
set的所有元素会根据其键值自动被排序。
set的键值(key)就是实值(value),实值就是键值。
set不允许两个元素有相同的键值。
因为set的元素值关系到其排列规则,所以不能通过set的迭代器改变set的元素值,
map
map的所有元素会根据其键值自动被排序。
map的所有元素都是pair,同时拥有键值key和实值value。
map不允许两个元素有相同的键值。
可以通过map的迭代器修改map元素的实值value,但不能修改元素的键值key,因为键值key关系到map元素的排列规则。
multiset
multiset与set的唯一差别:multiset允许键值重复,而set不允许。
multimap
multimap与map的唯一差别:multimap允许键值重复,而map不允许。
哈希表
哈希表中元素的存储位置由元素的key值和Hash函数共同确定,Hash函数根据元素的key值计算出该元素应在的位置。
A
d
d
r
e
s
s
=
H
a
s
h
(
k
e
y
)
Address = Hash(key)
Address=Hash(key)
哈希碰撞问题:不同的元素被映射到相同的位置。
哈希碰撞解决方法:
- 线性探测法:Hash出的位置H不可用时,往下一一寻找H+1、H+2、…、H+i,直到找到一个可用空间为止。
- 二次探测法:Hash出的位置不可用时,往下一一寻找H+1、H+4、…、H+i*i,直到找到一个可用空间为止。
- 开链法:Hash出的每个位置都维护一个链表。SGI STL采用此法。如下图所示。
unordered_set、unordered_map、unordered_multiset、unordered_multimap均以哈希表为底层结构。
unordered_set
unordered_set与set的唯一差别:unordered_set内的元素不会被自动排序,而set会。
unordered_map
unordered_map与map的唯一差别:unordered_map内的元素不会被自动排序,而map会。
unordered_multiset
unordered_multiset与multiset的唯一差别:unordered_multiset内的元素不会被自动排序,而multiset会。
unordered_multiset与unordered_set的唯一差别:unordered_multiset允许键值重复,而unordered_set不允许。
unordered_multimap
unordered_multimap与multimap的唯一差别:unordered_multimap内的元素不会被自动排序,而multimap会。
unordered_multimap与unordered_map的唯一差别:unordered_multimap允许键值重复,而unordered_map不允许。
图
暂不了解