C++ STL 容器、迭代器、适配器(深入了解,一文学会)

本文详细介绍了C++ STL中的容器(如vector、deque、list、map等)、迭代器及其适配器,涵盖了序列式、关联式、无序关联式容器的区别与使用场景,帮助开发者选择最适合的工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        什么是STL? STL,即标准模板库。高效的C++程序库。因为在各类C++ 项目中STL库都在广泛应用,包括作者在开发项目和对接第三方SDK、API的时候,尤其是封装过程中、接口、数据传输过程中都离不开STL模板的存在。vector、deque、list、forward_list、array、map/multimap、set/multiset。

        尤其是经常处理涉及万级别以上的数据量的时候传统的string int char 等数组,远远没有容器的处理效率以及不同的序列式容器、关联式容器、无序关联式容器、容器适配器等功能丰富。

STL 就位于各个 C++ 的头文件中,即它并非以二进制代码的形式提供,而是以源代码的形式提供。

        从根本上说,STL 是一些容器、算法和其他一些组件的集合,所有容器和算法都是总结了几十年来算法和数据结构的研究成果,汇集了许多计算机专家学者经验的基础上实现的,因此可以说,STL 基本上达到了各种存储方法和相关算法的高度优化。

C++ 标准模板库的核心包括以下三个组件:

        容器(Containers)        |        容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。

        算法(Algorithms)        |        算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。

        迭代器(iterators)              迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。

    本文作者原创,转载请附上文章出处与本文链接。

C++ STL 容器、迭代器、适配器(深入了解,一文学会)目录

1、STL容器

2、序列式容器

2.1、array容器

2.2、vector容器

2.3、deque容器

2.4、list容器

2.5、如何选择序列式容器

3、关联式容器

3.1、pair 类模板

3.2、map容器

3.3、set容器

4、无序关联式容器

4.1、unordered_map容器

4.2、unordered_set容器

5、容器适配器

 5.1、stack容器适配器

5.2、queue容器适配器详解

6、迭代器适配器

6.1、reverse_iterator反向迭代器适配器

6.2、insert_iterator插入迭代器适配器

6.3、stream_iterator流迭代器

6.4、streambuf_iterator流缓冲区迭代器

6.5、move_iterator移动迭代器

7、如何选择适合的容器


1、STL容器

        在实际的开发过程中,合理组织数据的存取与选择处理数据的算法同等重要,存取数据的方式往往会直接影响到对它们进行增删改查操作的复杂程度和时间消耗。事实上,当程序中存在对时耗要求很高的部分时,数据结构的选择就显得尤为重要,有时甚至直接影响程序执行的成败。

        值得一提的是,之前我们一直在不断地重复实现一些诸如链表、集合等等这些常见的数据结构,这些代码使用起来往往都十分类似,只是为了适应不同数据的变化,可能需要在一些细节上做不同的处理。

        那么大家有没有想过,是不是可以重复利用那些已有的实现来完成当前的任务呢?当然是可行的,有些读者已经亲自编写并实现了动态数组类、链表类、集合类等程序,并精心维护着。其实,STL 中提供了专家级的几乎我们所需要的各种容器,功能更好,复用性更高。

        其实上面话都比较官方容易理解,在实际应用中只需要会使用常见的几种容器就可以。但是其它容器还是有必要了解的,过一遍你总会发现某些功能应用在实际项目中很可能会达到很好的效果。

2、序列式容器

        所谓序列容器,即以线性排列(类似普通数组的存储方式)来存储某一指定类型(例如 int、double 等)的数据,需要特殊说明的是,该类容器并不会自动对存储的元素按照值的大小进行排序。       

        序列式容器分为 arrayvectordequelist 四种,每种类型容器的操作都可以高效执行,但进行除此之外的其他操作,效率会稍差一些。在这些容器当中很多容器函数的用法都有一样的地方。

2.1、array容器

        array 容器的大小是固定的,无法动态的扩展或收缩,这也就意味着,在使用该容器的过程无法借由增加或移除元素而改变其大小,它只允许访问或者替换存储的元素。

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118688364

2.2、vector容器

        vector 容器是 STL 中最常用的容器之一,它和 array 容器非常类似,都可以看做是对 C++ 普通数组的“升级版”。不同之处在于,array 实现的是静态数组(容量固定的数组),而 vector 实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector 会动态调整所占用的内存空间,整个过程无需人工干预。

        vector 常被称为向量容器,因为该容器擅长在尾部插入或删除元素,在常量时间内就可以完成,时间复杂度为O(1);而对于在容器头部或者中部插入或删除元素,则花费时间要长一些(移动元素需要耗费时间),时间复杂度为线性阶O(n)

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118676109

2.3、deque容器

        deque 容器和 vecotr 容器有很多相似之处和 vector 不同的是,deque 还擅长在序列头部添加或删除元素,所耗费的时间复杂度也为常数阶O(1)。并且更重要的一点是,deque 容器中存储元素并不能保证所有元素都存储到连续的内存空间中。

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118676574

2.4、list容器

        list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的。这意味着,list 容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中。

         详细请参考:https://blog.csdn.net/qq_37529913/article/details/118676917

2.5、如何选择序列式容器

        可以看标题“序列式容器”说明它是有序队列遵循先进先出,所以说这些容器都可以满足使用条件,只是四个容器处理数据的方向不同。

优点:

  • vector        :高效存取。存数据取数据较为高效。
  • list             :高效插入和删除。插入数据删除数据较为高效。
  • deque        :双端队列从前或者从后插入删除较快。

缺点:

  • vector        :插入和删除的效率较慢。
  • list             :存取速度较慢。
  • deque        :两端操作较快,中间较慢。

array升级版的普通数组,提升了普通数组的安全性,效率和普通数据一样。


3、关联式容器

        和序列式容器不同的是,关联式容器在存储元素时还会为每个元素在配备一个键,整体以键值对的方式存储到容器中。相比前者,关联式容器可以通过键值直接找到对应的元素,而无需遍历整个容器。另外,关联式容器在存储元素,默认会根据各元素键值的大小做升序排序。

        相比其它类型容器,关联式容器查找、访问、插入和删除指定元素的效率更高。

3.1、pair 类模板

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118714852

3.2、map容器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118741670

3.3、set容器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/118918940

4、无序关联式容器

        除了序列式容器和关联式容器之外,C++ 11 标准库又引入了一类容器,即无序关联式容器。

        无序关联式容器,又称哈希容器。和关联式容器一样,此类容器存储的也是键值对元素;不同之处在于,关联式容器默认情况下会对存储的元素做升序排序,而无序关联式容器不会。

        和其它类容器相比,无序关联式容器擅长通过指定键查找对应的值,而遍历容器中存储元素的效率不如关联式容器。

4.1、unordered_map容器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119689199

4.2、unordered_set容器

         详细请参考:https://blog.csdn.net/qq_37529913/article/details/119709019

5、容器适配器

        容器适配器中的“适配器”,和生活中常见的电源适配器中“适配器”的含义非常接近。我们知道,无论是电脑、手机还是其它电器,充电时都无法直接使用 220V 的交流电,为了方便用户使用,各个电器厂商都会提供一个适用于自己产品的电源线,它可以将 220V 的交流电转换成适合电器使用的低压直流电。

        从用户的角度看,电源线扮演的角色就是将原本不适用的交流电变得适用,因此其又被称为电源适配器。

 5.1、stack容器适配器

         详细请参考:https://blog.csdn.net/qq_37529913/article/details/119723782

5.2、queue容器适配器详解

         详细请参考:https://blog.csdn.net/qq_37529913/article/details/119746246

6、迭代器适配器

        C++ STL 标准库中迭代器大致分为 5 种类型,分别是输入迭代器、输出迭代器、前向迭代器、双向迭代器以及随机访问迭代器。

6.1、reverse_iterator反向迭代器适配器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119814820

6.2、insert_iterator插入迭代器适配器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119834378

6.3、stream_iterator流迭代器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119834429

6.4、streambuf_iterator流缓冲区迭代器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119850048

6.5、move_iterator移动迭代器

        详细请参考:https://blog.csdn.net/qq_37529913/article/details/119859888

7、如何选择适合的容器

虽然 STL 标准库还有迭代器、算法、函数对象等,但容器仍是大多数 C++ 程序员关注的焦点。首先,和普通数组相比,容器支持动态扩容和收缩,还可以自行管理存储的元素(例如排序),同时还提供有诸多成员方法,大大提高了开发效率等等。其次,每个容器的底层实现,都采用的是精心挑选的数据结构,这意味着在使用这些容器时,不用担心它们的执行效率。

总的来说,C++ STL 标准库(以 C++ 11 为准)提供了以下几种容器供我们选择:

  1. 序列式容器:array、vector、deque、list 和 forward_list;
  2. 关联式容器:map、multimap、set 和 multiset;
  3. 无序关联式容器:unordered_map、unordered_multimap、unordered_set 和 unordered_multiset;
  4. 容器适配器:stack、queue 和 priority_queue。

上面是依据容器类型进行分类的。实际上,每个容器所具有的特性都和其底层选用的存储结构息息相关。根据容器底层采用的是连续的存储空间,还是分散的存储空间(以链表或者树作为存储结构),还可以将上面容器分为如下两类:

  1. 采用连续的存储空间:array、vector、deque;
  2. 采用分散的存储空间:list、forward_list 以及所有的关联式容器和哈希容器。

 要想选择出适用于该特定场景的最佳容器,需要综合考虑多种实际因素,例如:

  • 是否需要在容器的指定位置插入新元素?如果需要,则只能选择序列式容器,而关联式容器和哈希容器是不行的;
  • 是否对容器中各元素的存储位置有要求?如果没有,则可以考虑使用哈希容器,反之就要避免使用哈希容器;
  • 是否需要使用指定类型的迭代器?举个例子,如果必须是随机访问迭代器,则只能选择 array、vector、deque;如果必须是双向迭代器,则可以考虑 list 序列式容器以及所有的关联式容器;如果必须是前向迭代器,则可以考虑 forward_list 序列式容器以及所有的哈希容器;
  • 当发生新元素的插入或删除操作时,是否要避免移动容器中的其它元素?如果是,则要避开 array、vector、deque,选择其它容器;
  • 容器中查找元素的效率是否为关键的考虑因素?如果是,则应优先考虑哈希容器。

    其它容器、迭代器请参考下列链接。

以下博客部分内容借鉴自:http://c.biancheng.net/stl/。

C++ STL 容器、迭代器、适配器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/120052137                                                                                C++ STL deque容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676574
C++ STL vector容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676109
C++ STL list容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118676917
C++ STL forward_list容器(深入了解,一文学会)               https://blog.csdn.net/qq_37529913/article/details/118687348
C++ STL array 容器(深入了解,一文学会)                        https://blog.csdn.net/qq_37529913/article/details/118688364
C++ STL pair 类模板(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118714852
C++ STL map容器(深入了解,一文学会)                           https://blog.csdn.net/qq_37529913/article/details/118741670
C++ STL map emplace()和emplace_hint()(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/118771777
C++ STL multimap容器(深入了解,一文学会)                    https://blog.csdn.net/qq_37529913/article/details/118773021
C++ STL Set容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118918940
C++ STL multiset容器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119624779
C++ STL unordered_map容器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/119689199
C++ STL unordered_set容器(深入了解,一文学会)           https://blog.csdn.net/qq_37529913/article/details/119709019
C++ STL unordered_multiset容器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/119709079
C++ STL stack容器适配器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119723782
C++ STL queue容器适配器(深入了解,一文学会)       https://blog.csdn.net/qq_37529913/article/details/119746246
C++ STL priority_queue容器适配器(深入了解,一文学会)                https://blog.csdn.net/qq_37529913/article/details/119770527
C++ STL reverse_iterator反向迭代器适配器(深入了解,一文学会)   https://blog.csdn.net/qq_37529913/article/details/119814820
C++ STL insert_iterator插入迭代器适配器(深入了解,一文学会)      https://blog.csdn.net/qq_37529913/article/details/119834378
C++ STL stream_iterator流迭代器(深入了解,一文学会)                  https://blog.csdn.net/qq_37529913/article/details/119834429
C++ STL streambuf_iterator流缓冲区迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119850048
C++ STL move_iterator移动迭代器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119859888
C++ STL advance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008250
C++ STL distance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008300
C++ STL iterator迭代器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008346
C++ STL const_iterator转换为iterator类型迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008324
C++ STL begin()和end()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008459
C++ STL prev()和next()函数(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008481
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双子座断点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值