C++ STL容器

容器

  • 容器(container)用于存放数据的类模板。STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。

  • 顺序性容器 是 一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。这个位置和元素本身无关,而和操作的时间和地点有关,顺序性容器不会根据元素的特点排序而是直接保存了元素操作时的逻辑顺序。

    • vector(可以看作动态数组)、list (双向链表)、deque (双端队列)
  • 关联式容器 和 顺序性容器不一样,关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置 入容器时的逻辑顺序。

    • set、multiset、map、multimap
  • 容器适配器 是一个比较抽象的概念,适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器是让一种已存在的容器类型采用另一种不同的抽象类型的工作方式来实现的一种机制。适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。

    • stack、queue、priority_queue

迭代器

迭代器:一种抽象的设计概念,在设计模式中有迭代器模式,即提供一种方法,使之能够依序寻访某个容器所含的各个元素,而无需暴露该容器的内部表述方式。

作用:在无需知道容器底层原理的情况下,遍历容器中的元素。

​ 要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行(迭代器是c++中才有的。)。

​ 迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素。

​ 对正向迭代器进行++操作时,迭代器会指向容器中的后一个元素;而对反向迭代器进行++操作时,迭代器会指向容器中的前一个元素。

例:vector<int>::iterator i; for(i = v.begin(); i != v.end(); i++) cout << *i <<endl;

容器适配器 stack、queue 和 priority_queue 没有迭代器。

​ 容器都有的成员begin()和end(),其中begin返回指向第一个元素的迭代器,而end成员返回指向容器尾元素的下一个位置的迭代器,也就是说end指示的是一个不存在的元素,所以叫end返回的是尾后迭代器。一般使用auto或者decltype来定义。

红黑树有自动排序功能,哈希表没有,且哈希表消耗比较多的内存,但复杂度可以达到常数。

实现插入查找删除
map红黑树O(logn)O(logn)O(logn)
unordered_map哈希表平均O(1), 最坏O(N)平均O(1), 最坏O(N)平均O(1), 最坏O(N)
set红黑树O(logn)O(logn)O(logn)
unordered_set哈希表平均O(1), 最坏O(N)平均O(1), 最坏O(N)平均O(1), 最坏O(N)
hash_map哈希表平均O(1), 最坏O(N)平均O(1), 最坏O(N)平均O(1), 最坏O(N)

map、unordered map

  • map:内部实现了一个红黑树,具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。

  • unordered_map:unordered_map内部实现了一个哈希表,其元素的排列是无序的

map:

优点:1、有序性 2、红黑树,使得map的很多操作在logn的时间复杂度下就可以完成,效率很高

缺点:因为内部实现是用了红黑树,每个结点都需要额外保存父子结点和红黑性质,因此占用的空间多,空间占用率高。

适用性:对有顺序要求的问题会更高效

unordered_map:

优点:内部实现哈希表,查找速度很快

缺点:哈希表的建立比较耗时

适用性:对于查找问题会更高效

map时间复杂度:插入查找删除都是O(logn)

unordered_map时间复杂度:插入查找删除都是平均O(1),最坏O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值