容器
作用:存放数据
序列式容器
array
静态数组,大小固定的数组
vector
动态数组,支持随机访问迭代器,逻辑结构和物理结构相似
在GCC下两倍增长,在VC下1.5倍增长
deque
双端队列,支持随机访问迭代器
逻辑结构:连续空间,双端开口
物理结构:在内存中由多个片段构成的,片段内部是连续的,但是片段之间不连续。
forward_list
单链表,支持前向访问迭代器
list
双向链表,支持双向访问迭代器
物理结构:循环双向链表
逻辑结构:双向链表
线性容器总结
位置 | 使用 |
---|---|
需要频繁的在容器中间位置添加/删除元素 | list |
需要频繁的在容器头部位置添加/删除元素 | deque/list |
需要频繁的在容器尾部位置添加/删除元素 | vector/deque/list |
需要频繁的在容器头部,尾部添加/删除元素 | deque/list |
需要频繁地访问任意位置上的元素 | vector/deque |
关联式容器
共性
底层实现都是红黑树,红黑树是一种近似的平衡二叉树
查找元素的时间复杂度为O(LogN) 二分查找
默认情况下按照升序的方式进行排列
不能修改关键字的值
支持的是双向访问迭代器
set
不能存储重复的关键字Key
不支持下标访问运算符
模板:
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
初始化:
set<int> number={1,12,325,446,47};
set不支持下标与修改
set针对自定义类型,必须要实现Compare,也就是std::less或者std::greater
multiset
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class multiset;
可以存储重复的Key
与set的区别
set与multiset的初始化、遍历、查找、删除的使用都一样,都不支持下标访问、都不支持修改。对于
insert插入而言,multiset肯定可以插入成功,所以二者返回类型不一样,至于插入迭代器返回与大括
号类型都是一样的。
map
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
1,存放的关键字Key不重复,按照key值升序
2,支持下标访问运算符
3,存放的元素是一个pair类型,key与value值,key是唯一的,不能重复的,但value值重复与否是没关系的
初始化:
map<int,string> number={
{3,"武汉"},
{4,"上海"},
{5,"武汉"},
pair<int,string>(6,"北京"),
pair<int,string>(7,"天津"),
make_pair(8,"杭州"),
make_pair(9,"重庆"),
}
multimap
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;
可以存储重复的Key
multimap不支持下标访问,key值相同的时候,value有可能不一样
无序关联式容器
底层实现——哈希表
哈希函数
通过key值,可以找到key值对应的value
size_t idx=H(key);
哈希函数的设计
直接定址法,平方取中法,数字分析法,除数取余法。
哈希冲突
不同key值,对应相同的value值
key1不等于key2,但是
H(key1)=H(key2)
哈希冲突的解决方式
1,开放定址法
2,链地址法(推荐使用这种方法,STL中使用的方法)
3,再散列法
4,建立公共溢出区
存放的元素是无序的
针对自定义类型必须给出hash函数,必须重载operator=
unordered_set
template<
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>
> class unordered_set;
不能存储关键字相同的元素
不能用下标访问运算符
unordered_set<int> qq ={1,9,9,3,0,9,5,6,2,2};
unordered_multiset
unordered_set<int> qq ={1,9,9,3,0,9,5,6,2,2};
可以存放关键字相同的元素
unordered_map
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
不能存放关键字相同的元素
可以使用下标访问运算符
unordered_multimap
可以存放关键字相同的元素
如何选择合适的容器
如果元素是连续存储的
序列式容器,vector
查找数据的时候,时间复杂度
O(1):四个无序关联式容器 vector
O(logN):四种关联式容器
可以使用下标
vector,deque,map,unordered_map
下标具有插入操作的
map或者unordered_map
以使用下标访问运算符
unordered_multimap
可以存放关键字相同的元素
如何选择合适的容器
如果元素是连续存储的
序列式容器,vector
查找数据的时候,时间复杂度
O(1):四个无序关联式容器 vector
O(logN):四种关联式容器
可以使用下标
vector,deque,map,unordered_map
下标具有插入操作的
map或者unordered_map