主要包括三类:算法、容器和迭代器
vector
数组
高效随机访问
动态查找超过自身容量的需要申请大两倍的拷贝过程
当插入(push_back)一个元素后,end 操作返回的迭代器肯定失效。若 capacity 返回值没有改变,则 first 返回的迭代器依旧有效;否则,first迭代器也失效
list
链表
任意位置插入、删除元素是常量时间复杂度
删除操作也只有指向被删除元素的那个迭代器失效,其他迭代器不受影响
deque
数据模式是数组和链表的这种(是stack和queue的基础),双向链表
在容器首部尾部插入元素不会使得任何迭代器失效,但是其他位置的插入和删除操作会使得所有的迭代器失效
在首部或尾部删除元素,只会使得被删除的元素的迭代器失效
Map
mmuitimap
set
multiset
vector可以根据需要自动扩大容器的大小。不够用时,会重新申请大原来容量两倍的内存,将原容器拷贝到新容器,并释放原空间,返回新空间的指针
因此对于频繁插入,最好先指定vector的大小。因为容量不够时,每次调用push_back都会重新分配新的空间
pushu_back:首先会调用构造函数创建这个临时对象,然后调用拷贝构造函数将这个临时对象放入容器中,最后是释放原来的临时对象。
引入了右值引用,转移构造函数后,push_back()右值时就会调用构造函数和转移构造函数,如果可以在插入的时候直接构造,就只需要构造一次即可
emplace_back:在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。
数据量较大时,采用快速排序,分段递归
数据量小于某个阈值(16)时,改用插入排序
为避免递归调用带来的负荷,递归达到一定程度采用堆排序
递归会导致栈溢出:因为每次调用递归函数都会在栈中分配空间,每个进程的栈空间容量都是有限的。
堆排序数据访问方式没有快速排序友好。快速排序是顺序访问的,堆排序数据是跳着访问的。
同样的数据,堆排序算法数据交换次数要多于快速排序
STL中的hash表就是unordered_map。使用的是哈希进行实现。记录的键是元素的哈希值。
unordered_map的底层实现是hashtable,采用开链法(也就是桶)来解决哈希冲突,当桶的大小超过8时,就自动转为红黑树进行组织。
关联容器(list,set map)不需要做内存拷贝和内存移动。变换的时候,只需要堆指针进行操作即可
map的内部实现是二叉平衡树(红黑树),有序的
unordered_map:哈希表,无序的
set不能直接改变元素的值。需要先删除旧元素,在插入新元素
map的key是不能修改的,但是可以通过key改变value的值
queue:除了头部外,没有其他方法存取deque的其他元素
stack:除了最顶端外,没有任何其他方法可以存取stack的其他元素