C++STL容器总结

C++ STL容器小总结

写在前面

学习C++有一段时间了,写篇博客来记录下学习的心得,如有错误欢迎批评指出。顺便回顾一下STL顺序容器的知识,是对本科所学习的数组、链表、栈或队列的一个小进阶。平时用的多的应该就是这几个顺序容器:vector,string,list,forward_list,deque,array,容器适配器(stack,queue,priority_queue)。
总的来说,新标准库的容器要比旧版本快得多,性能甚至可以超越精心设计的同类数据结构,所以在现代的C++程序中,应该使用STL容器而不是原始的数据结构。

vector

支持随机访问和容量增减,能够像数组一样使用下标的方式访问元素,也可以使用大多数容器支持的解引用方式访问vector元素。它是应用情况最广的顺序容器,书上原话是:除非你有很好的理由选择其他容器,否则应该使用vector。
vector在尾部增加或删除元素的操作v.push_back,v.pop_back能够达到很高的效率,但在中间insert元素效率比较低,可能会导致需要重新分配内存。这是因为在底层实现过程中为了减少给vector重新分配内存的次数,在多次分配时会分配一点额外的空间(一般以2的次方增长),这个使用v.reserve()设置,用v.capacity()能返回实际内存的大小,而不像v.size()返回的是vector中已有的元素个数。重新分配导致的结果可能是 所有指向vector的迭代器失效。一般地我们不会将end拿来赋给我们程序中所使用的迭代器,因为当vector大小发生变化时,end也会随着一起发生变化,例如添加或删除一个元素,将会导致这个元素后面的迭代器全部失效。

string

由于本科直接学的C++(没学好),以致于很长一段时间我都认为string是像char一样的一种基本的数据类型。直到回过头学C的时候经常使用字符数组才明白,string是为了简化字符数组的操作而存在。在这里直接将string视为是字符的顺序容器。它和vector很类似,但专门用于保存字符,支持下标随机访问,速度快,在尾部插入或者删除速度很快,但如果在中间插入字符的话会比较慢,因为需要将后面的字符全部向后移,甚至还要重新分配内存空间。但总的来说,下标访问容易越界,所以尽量还是使用迭代器。
字符串拼接s1.append(s2),很像python中的list。字符串截取substr,字符替换replace,字符删除(可范围删除)erase,字符串搜索find,反向搜索rfind,比较s1.compare(s2)类似于strcmp.

list

双向链表,只支持双向的顺序访问,在任意位置插入和删除元素都有很高的效率。这种容器的空间开销比较大,要访问具体元素时只能通过遍历的方法。
因为双向,所以既可以++也可以–,但由于存储空间不是连续的所以不可以+n-n,链表加入和删除元素迭代器不会失效,除非删除的是迭代器指向的元素。 另外,它还有pop_front和push_front的操作。

forward_list

单向链表或者叫前向链表,单向顺序访问,任意位置插入删除效率高。它比较特殊,定义的不是insert、emplace、erase,它有个独有的before_begin迭代器指向首个元素的前面,它使用insert_after、emplace_after、erase_after。同list,插入删除操作不会使迭代器失效。

array

可以看成是老牌数组,固定长度,可以快速的随机访问,不可以删除或者增加元素。

deque

双端队列。擅长在头部或者底部进行添加或者删除的操作,并且不会导致内存的重新分配,支持快速的随机访问。底层存储是由一段一段等长的连续空间构成,空间之间不一定连续,另外用了一个数组存储下指向每段连续空间的指针。所以迭代器的实现比较复杂,等看了STL源码剖析再来完善它的底层原理。

容器适配器

本质上,容器适配器是一种机制,能使某一种事物看起来像另外一种事物。例如stack适配器可以接受一个顺序容器(除array和forward_list),使得这个顺序容器的操作像栈一样。此时容器会失去一些共性操作,例如push_back,而只能使用特有的push。
stack适配:先进后出,pop顶部弹出,push顶部插入,top返回顶部元素
queue适配:先进先出,pop顶部弹出,push底部插入
priority_queue优先级队列适配:它具有优先级最高先出的特征,内部一直是按优先级有序的,底层采用堆来实现,每次push一个新的元素会重排,不过堆排序效率还是比较高的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值