C++中容器(STL)

一、什么是容器?

  • 所谓容器,就是可以承载,包含元素的一个器件,它是STL六大组件之一,是容器、算法、迭代器中最重要也是最核心的一部分
     
  • 二、STL中各大容器的结构与分类

    2.1 顺序性容器

    2.1.1 什么是顺序性容器?

    顺序性容器就是将一组具有相同类型的元素以严格的线性形式组织起来
  • 2.1.2 有哪些顺序性容器?

    2.2 关联式容器

    2.2.1 什么是关联式容器?

    关联式容器每一个元素都有一个键值(key),对于二元关联容器,还拥有实值(value)容器中的元素顺序不能由程序员来决定,有set(集合)和map(映射)这两大类,它们均是以RB-Tree(red-black tree,红黑树)为底层架构。

    2.2.2 有哪些关联式容器?

2.23 迭代器的有无

三、vector扩大容量的本质

另外需要指明的是,当 vector 的大小和容量相等(size==capacity)也就是满载时,如果再向其添加元素,那么 vector 就需要扩容。vector 容器扩容的过程需要经历以下 3 步:

  1. 完全弃用现有的内存空间,重新申请更大的内存空间;
  2. 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
  3. 最后将旧的内存空间释放。
  4. 这也是vector 容器在进行扩容后,与其相关的指针、引用以及迭代器可能会失效的原因。

3.12.如何避免扩容导致效率低

如果要避免扩容而导致程序效率过低问题,其实非常简单:如果在插入之前,可以预估vector存储元素的个数,提前将底层容量开辟好即可。如果插入之前进行reserve,只要空间给足,则插入时不会扩容,如果没有reserve,则会边插入边扩容,效率极其低下。

reserve(100)函数就是vector扩容的api

一.扩容
Size()——返回当前的vector的元素个数。
Capacity()—返回当前vector当前能够返回的个数,就是扩容之后的大小。

size();    //返回容器中元素的个数
empty();   //判断容器是否为空
resize(int num);    //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem);    //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长>度的元素被删除。
capacity();               //容器的容量
reserve(int len);         //容器预留len个元素长度,预留位置不初始化,元素不可访问。


at(int idx);     //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
operator[];      //返回索引idx所指的数据,越界时,运行直接报错
front();         //返回容器中第一个数据元素
back();          //返回容器中最后一个数据元素


insert(const_iterator pos, int count,ele);    //迭代器指向位置pos插入count个元素ele.
push_back(ele);     //尾部插入元素ele
pop_back();         //删除最后一个元素
erase(const_iterator start, const_iterator end);    //删除迭代器从start到end之间的元素
erase(const_iterator pos);    //删除迭代器指向的元素
clear();                      //删除容器中所有元素

3.2、vector和list的区别

1、vector拥有一段连续的内存空间,如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、list拥有一段不连续的内存空间,因此支持随机存取,如果需要大量的插入和删除,而不关心随即存取,则应使用list。
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

3.3 迭代器失效问题

在C++中,容器迭代器会在某些操作之后失效。以下是一些常见的C++容器及其导致迭代器失效的操作:

  1. std::vector:

    • 在插入或删除元素时,可能会导致迭代器失效。因为插入或删除元素后,原本位于被修改位置后面的元素会发生移动,导致原迭代器指向的位置不再有效。
  2. std::deque:

    • 在插入或删除首尾以外的元素时,可能会导致迭代器失效。因为插入或删除元素后,原本位于被修改位置后面的元素会发生移动,导致原迭代器指向的位置不再有效。
  3. std::list:

    • 在插入或删除元素时,不会导致迭代器失效。std::list使用链表实现,插入或删除元素只会影响相应节点的连接,不会影响其他节点。
  4. std::setstd::mapstd::multisetstd::multimap:

    • 在插入元素时,不会导致迭代器失效。但在删除元素时,会导致指向被删除元素的迭代器失效。因为删除元素后,原迭代器指向的位置不再有效。
  5. std::unordered_setstd::unordered_mapstd::unordered_multisetstd::unordered_multimap(C++11中引入的无序容器):

    • 在插入或删除元素时,可能会导致迭代器失效。因为这些容器使用哈希表实现,插入或删除元素可能会导致重新哈希和重排桶,从而使原迭代器指向的位置不再有效。

需要注意的是,即使不发生迭代器失效,容器的元素插入或删除也可能会导致迭代器的范围失效。在进行删除操作后,应当小心更新迭代器,以避免使用失效的迭代器。

此外,对于所有容器,当对容器进行结构性修改时(例如重新分配内存,改变容器大小),所有迭代器都会失效。因此,在这种情况下,应当谨慎操作迭代器或重新获取迭代器。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值