c++标准库中各种容器的介绍

这篇文章最早发布于关门2000的博客(www.gscience.cc)中。原文章为C++标准库中的容器,转载请注明

这篇文章参考于cppreference.com。在这篇文章中我们将介绍每种容器的特点,并不会去介绍详细的使用方法。

顺序容器:

array

array( 数组)是一种最简单的标准库容器,定义于头文件<array>中:
template< 
    class T, 
    std::size_t N 
> struct array;
array的功能基本与普通的C数组,性能也是如此,只不过拥有了一些C++标准容器的特性例如查询大小、复制、迭代等。

vector与deque

vector(容器)中的内存是连续的,所以我们除了可以利用迭代器之外,还可以通过指针的偏移来访问其中的元素。vector定义于头文件<vector>中:
template<
    class T,
    class Allocator = std::allocator<T>
> class vector;
vector会在需要的时候动自动调整占用的内存的大小,与静态的array相比,vector占用的内存会更多,这一设计是为了降低重新分配内存的频率。我们可以通过capacity()来查询已分配的内存,通过shrink_to_fit()来归还已经分配的空闲的内存。我们可以随意向vector的任何位置添加、删除元素,但是只有在结尾删除元素的速度是最快的。同时如果对vector的大小有个预估,可以通过reserve()函数来为vector分配内存。  vector 上常见操作的复杂度(效率)如下:
  • 随机访问 - 常数 O(1)
  • 在尾部增删元素 - 平摊(amortized)常数 O(1)
  • 增删元素 - 至 vector 尾部的线性距离 O(n)
提示:请不要试图使用vector<bool>,他会造成很严重的性能问题,甚至在新版的编译器中已经无法编译。
与vector相反,deque(双向队列)其中的数据并不是连续储存的。deque允许在头部和尾部快速插入、删除元素。他定义在头文件<deque>中:
template<
    class T,
    class Allocator = std::allocator<T>
> class deque;
与vector类似,deque也会自动扩容。但是扩容deque的成本更低,因为deque不需要保证元素的连续性。同样,deque也是支持迭代器的。同时,向deque中插入元素不会使原有的指向元素的指针实效。

deque上常见操作的复杂性(效率)如下:

  • 随机访问 - 常数O(1)
  • 在结尾或开头插入或移除元素 - 摊销不变O(1)
  • 插入或移除元素 - 线性O(n)
deque的原理比vector复杂的多,以后会去写一篇专门研究deque的文章。

list与forward_list

list( 列表)支持任意位置的快速插入和删除,但是作为代价,他并不支持随机访问。list通常实现为双向的链表,定义于头文件<list>中:
template<
    class T,
    class Allocator = std::allocator<T>
> class list;
与list相比,forward_list( 单向列表)只支持单向迭代,但其拥有更高的空间利用率。forward_list定义于头文件<forward_list>中:
template<
    class T,
    class Allocator = std::allocator<T>
> class forward_list;

关联容器:

set与multiset

set是一个关联型容器,不支持随机访问。定义在头文件<set>中:
template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;
set( 集合)中包含不重复、类型Key的元素。相反的,在multiset( 多重集合)中的元素是可以重复的,multiset也定义于头文件<set>中:
template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class multiset;
提示:无论是set还是multiset,都可以通过类型为Compare的比较函数来实现排序的。若遇到相等元素则他们的顺序就是插入时的顺序且不会改变。

map与multimap

map(映射是一个有序关联容器,不支持随机访问。定义在头文件<map>中:
template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
在map中,包含具有唯一键的键值对。键通过比较函数Compare来排序,通常被现为红黑树。如果需要一个键对应多个元素,就需要使用multimap( 多重映射)。multimap定义于头文件<map>中:
template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;
提示:请尽量不要去遍历map和multimap,他们的设计决定了遍历的速度会很慢。

unordered_set,unordered_multiset和unordered_map

unordered_set(无序集合)是一个关联型容器,定义于头文件<unordered_set>中:

template<
    class Key,
    class Hash = std::hash<Key>,
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator<Key>
> class unordered_set;

unordered_multiset(无序多重集合)是一个关联型容器,定义于头文件<unordered_multiset>中:

template<
    class Key,
    class Hash = std::hash<Key>,
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator<Key>
> class unordered_multiset;

unordered_map(无序映射)是一个关联型容器,定义于头文件<unordered_map>中:

template<
    class Key,
    class T,
    class Hash = std::hash<Key>,
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;

unordered_multimap(无序多重映射)是一个关联型容器,定义于头文件<unordered_multimap>中:

提示:以上四种无序容器通常都是用哈希表实现的,搜索,插入和去除具有平摊的常数时间复杂度,但是作为代价其内存占用会很高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值