STL容器及简单使用总结

STL ( Standard Template Library) 的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL是C++的一部分,因此不用安装额外的库文件。

STL是一种泛型编程。面向对象编程关注的是编程的数据方面,而泛型编程关注的是算法。(不是很懂)

STL主要包括容器(containers)和算法(algorithms),以下是自己对几个主要的STL容器的理解。

STL容器

vector

向量,连续的空间存储,可以使用[]操作符。一个动态分配存储空间的容器,在插入新的元素后,会自动重分配(扩展)空间。

可以快速的在末尾插入元素,但是在序列中间的插入/删除元素要慢,而且如果一开始分配的空间不够的话,有一个重新分配更大空间,就会产生拷贝的性能开销。

list

双向链表,每个元素间用链表相连,可以非连续空间存储。不能使用[]操作符。

访问随机元素不如vector快,随机的插入元素比vector快,对每个元素分配空间,所以不存在空间不够,重新分配的情况。所以list更适合 需要在任意位置频繁插入/删除操作的情况。

queue

单向队列,也就是一个先进先出的FIFO,不能使用[]操作符。不能访问中间元素,只能访问首尾的元素。

deque

双向队列,可以使用[]操作符。

Queue是单向push,单向pop;而deque是双向(既可以从front方向,也可以从back方向) 都可以push和pop。

小片的连续,小片间用链表相连,实际上内部有一个map的指针。

快速的在开始和末尾插入元素;随机的插入/ 删除元素要慢;空间的重新分配要比vector快。

set

集合,关联容器,只有key值,元素唯一,不允许重复。

内部用一棵平衡树结构来存储,每次insert都会重新进行排序,查找也比较快

参考 《C ++ Primer》P378 关键字类型要求,默认情况下,标准库使用关键字类型的< 运算符来比较两个关键字。对于set 和map,是按照这个 < 关系来进行排序的。

我们不能直接定义一个 自定义类型的set或map,因为其没有 < 运算符,需要自己对自定义类型规定一个 < 运算符,以后有机会再专门讨论这个话题。

mutilset

元素允许重复

map

关联容器,一对一的映射的结合<key, value>,key不能重复。

可以通过insert(std::pair<key,value>)插入元素,或者直接 [key] =value进行插入。

可以直接使用[key]得到这个元素的value值。

对于set和map,要习惯使用迭代器iterator。

map插入元素的两种方式: insert 和[] 是有区别的 。 insert 一个元素,如果元素key值已经存在,则不作任何处理,原来元素的value值不变。而[] 遇到已经存在的key值,直接修改原来元素的value。Map的insert和[]操作符的区别_wozaiwogu的博客-CSDN博客

multimap

Key值可以重复

C语音中的数组也是连续存储,数组和vector的主要不同点在于vector可以随时增加长度,但数组的长度是在定义时就确定好了的。

Vector

数组

可以用size获取vector的长度

不可以获取,在定义时就已经确定了长度

长度不固定,可以随时增加

长度固定,在定义是就不可以更改

可以在末尾增加vector的元素(用push_back)

不能增加在长度以外的长度

不能确定长度,必须在定义时定义一个很大的空间留给数组,造成内存的浪费

可以确定长度,节约空间

可以用size获取vector的长度

不可以获取,在定义时就已经确定了长度

Vector、list、queue、deque都属于顺序容器,那怎么来选择用哪一种容器呢?

下面是选择顺序容器类型的一些准则

  1. 如果我们需要随机访问一个容器,则vector要比list好得多 。
  2. 如果我们已知要存储元素的个数,则vector 又是一个比list好的选择。
  3. 如果我们需要的不只是在容器两端插入和删除元素,则list显然要比vector好 。
  4. 除非我们需要在容器首部插入和删除元素,否则vector要比deque好。
  5. 如果只在容易的首部和尾部插入数据元素,则选择deque。

原文链接:C++中数组、链表和vector等容器之间的区别_无鞋童鞋的博客-CSDN博客

各个STL容器的示例代码和函数用法都可以从网上直接找到,推荐这两个网址:

cplusplus.com - The C++ Resources Network

C reference - cppreference.com

需要注意的是,在使用set和map时,因为key是唯一的,如果你insert了相同key值的元素,则会覆盖掉之前的元素(map的value值变成新插入的)。如果你使用[]来插入了相同key值的元素,则会覆盖掉之前的元素(map的value值变成新插入的),而如果使用insert,则新的元素并没有被真的插入。所以,为了避免不必要的debug工作,养成好的编码习惯:

  1. 在往set或map中插入新元素之前,先check是否已经有相同key的元素了,如果有,就assert。
    std::map<key type, value type>::iterator it = m_map.find( key_element );
    assert(it ==m_map.end());
    m_map[key_element] = value ;

  2. 在准备erase set或map中的元素时,先check是否存在这个key的元素。
    std::map<key type, value type>::iterator it = m_map.find( key_element );
    assert(it !=m_map.end());
    m_map.erase(it);

    同时,在使用STL容器的时候,一定要特别注意,有insert就需要有erase,否则内存会爆掉的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

123axj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值