1、STL的六大组件
1.容器 2.算法 3.迭代器 4.配置器allocators 5.仿函数functor 6.配接器adapters
2、典型STL容器的用处、区别
2.1序列容器和关联容器的区别和种类
- 区别
根据“数据在容器中的排序特性”将容器分为序列容器和关联容器。
两者的区别包括:
- 元素组成:序列容器元素只有实值,关联容器元素存在一个键值和一个实值
- 序列容器不涉及排序,关联容器涉及排序
- 本质区别:序列容器依据元素的位置存储访问,而关联容器依据键值存储访问,所以关联容器也没有所谓头尾,只有最大最小元素。
(此外,除了STL标准库中提供有序容器,底层机制是红黑树,还有boost库中提供的无序关联容器底层机制是散列表,如unorder_map、unorder_multimap、unorder_set、unorder_multiset)
- 种类
序列容器有:
vector、list、deque,而queue、stack是以deque为底层的容器配接器。
2.2vector和array的区别
- array是C++本身提供的一种序列容器,vector是STL提供的序列容器
- array和vector的本质区别是,array是静态空间,一旦配置就不能改变,而vector是动态空间,随着元素的加入其内部机制会自行扩充空间以容纳新的元素。
- 因此,array在定义时必须使用常量或常量表达式指定大小。
- 存储位置上,array存储在栈上,而vector存储在堆上,其内部利用new和delete来管理内存。
vector和array是数组的替代品,相较于数组更加安全,封装之后使用也更加方便。
2.3vector和list的区别
vector是维护线性连续空间,而list是动态链表,两者都是在堆上分配空间
1、区别:
1)vector底层实现动态数组,list底层实现的双向链表。
2)vector支持通过下标随机访问,list不支持。且由于vector顺序存储所以vector访问时间复杂度更小。
3)插入删除方面:vector在中间插入或删除节点,会造成内存拷贝,数据元素的移动;list只需要对指针进行操作,不需要移动数据元素,时间复杂度更低。
4)内存使用上:vector一次性分配好内存,不够时才进行2倍扩容;list每次插入新节点都会进行内存申请。
5)此外,vector中只需要存储数据元素,list还需要维护指针信息。
2、应用
vector拥有一段连续的内存空间,因此支持随机访问,如果需要高效的随机访问,而不在乎插入和删除的效率,使用vector。
list拥有一段不连续的内存空间,如果需要高效的插入和删除,而不关心随机访问,则应使用list。
2.4deque
deque融合了vector和list的机制,是一组分段连续的空间。
deque和vector的相同之处是两者都是逻辑上的连续空间,插入删除操作的时间复杂度都比较高。
deque和vector的不同之处。6(主要两个方面生成长方向,不连续,管理复杂)
- vector是物理上的连续空间,而deque是一组分段的连续空间。
- vector是单向生长在尾部添加元素比较迅速,而deque是双向生长。
- 占用空间方面:vector只需存储数据元素,而deque除了存储数据元素之外,还需要维护一块主控单元。
- 由于是分段存储,所以deque的数据存取和迭代器的操作效率要慢于vector
- 但是另一方面也不需要在内存重分配时拷贝所有元素。
- 此外,deque不提供预留空间的reserve接口,由系统自动分配和回收。
2.5Queue和stack
这两个都是底层容器可以是list也可以是deque,是容器配接器,(修改某种接口,使之呈现另一种风貌)
这两个与其他容器的区别是,限定了元素的存取位置,和读取的位置,此外能够遍历,不能通过迭代器进行操作。
2.6请你来说一下map和set有什么区别,分别又是怎么实现的?
map和set都是STL的有序关联容器,两者的底层机制都是红黑树,两者的操作行为大都是调用红黑树的提供的操作实现。
区别:
- map中的元素由实值和键值组成,键值充当索引的作用,实值表示与键值关联的数据;set的元素就是其键值。
- map的实值可以修改,键值不可以修改;而set中的值就是键值,所以不可以修改,键值的修改会改变容器中其他数据的排列。
- map支持下标索引操作不支持,不过map下标索引在元素不存在时会存入一个实值为默认值的元素,如果不希望在不存情况下插入的话最好不要使用。
(map和multimap的区别,后者键值允许重复。map调用的插入机制是insert_unique,multimap调用的插入机制是insert_equal)
2.7红黑树的相关知识
红黑树是一种平衡二叉树,具有如下特征:
- 每个节点不是红色就是黑色;
- 根节点必须为黑色;
- 红色节点的子节点一定为黑色;
- 任意一个节点至NULL节点的路径上的黑色节点数目是相同的。
以上的规则意味着插入的节点一定要是红色,其父亲节点必须为黑。如果不满足的话就需要进行颜色调整或旋转树形。