STL的容器可以分为以下几个大类:
一:序列容器, 有vector, list, deque, string.
二 : 关联容器, 有set, multiset, map, mulmap, hash_set, hash_map, hash_multiset, hash_multimap
三: 其他的杂项, stack, queue, valarray, bitset
STL各个容器的实现:
(1) vector
内部数据结构:数组。
随机访问每个元素,所需要的时间为常量。
在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。
可动态增加或减少元素,内存管理自动完成,但程序员可以使用reserve()成员函数来管理内存。
vector的迭代器在内存重新分配时将失效(它所指向的元素在该操作的前后不再相同)。当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效;否则,指向当前元素以后的任何元素的迭代器都将失效。当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。
(2)deque
内部数据结构:数组。(访问元素、删除增加元素性质与vector相同)
可动态增加或减少元素,内存管理自动完成,不提供用于内存管理的成员函数。
增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。
(3)list
内部数据结构:双向环状链表。可双向遍历。
不能随机访问一个元素。在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。
可动态增加或减少元素,内存管理自动完成。
增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。
(4)slist
内部数据结构:单向链表。
不可双向遍历,只能从前到后地遍历。
其它的特性同list相似。
(5)stack
适配器,它可以将任意类型的序列容器转换为一个堆栈,一般使用deque作为支持的序列容器。
元素只能后进先出(LIFO)。不能遍历整个stack。
(6)queue
适配器,它可以将任意类型的序列容器转换为一个队列,一般使用deque作为支持的序列容器。
元素只能先进先出(FIFO)。不能遍历整个queue。
(7)priority_queue
适配器,它可以将任意类型的序列容器转换为一个优先级队列,一般使用vector作为底层存储方式。
只能访问第一个元素,不能遍历整个priority_queue。第一个元素始终是优先级最高的一个元素。
(8)set
键和值相等。键唯一。元素默认按升序排列。
如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。
(9)multiset
键可以不唯一。其它特点与set相同。
(10)hash_set
与set相比较,它里面的元素不一定是经过排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然跟hash函数有关)。
其它特点与set相同。
(11)hash_multiset
键可以不唯一。其它特点与hash_set相同。
(12)map
键唯一。元素默认按键的升序排列。
如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。
(13)multimap
键可以不唯一。
其它特点与map相同。
(14)hash_map
与map相比较,它里面的元素不一定是按键值排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然也跟hash函数有关)。
其它特点与map相同。
(15)hash_multimap
键可以不唯一。
其它特点与hash_map相同
Stack的声明如下:
template<typename _Tp, typename _Sequence = deque<_Tp> >
class stack;
第一个template代表元素类型;第二个template代表stack内部存放元素所用的实际容器,缺省用deque。
之所以选择deque而不是vector是因为:
1.deque移除元素时候会释放内存,
2.deque不必在重新分配内存是复制全部元素
实际上,stack只是很单纯的把各项操作转换为内部容器的对应调用。这从其实现代码也可以看出,下面是stack的源代码,这里去掉了value_type等声明和构造析构函数等,主要列举了几个常用的接口:
protected:
_Sequence c; ///内部容器
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference top() ///注意top返回的是reference
{
__glibcxx_requires_nonempty();
return c.back();
}
const_reference top() const
{
__glibcxx_requires_nonempty();
return c.back();
}
void push(const value_type& __x)
{ c.push_back(__x); }
void pop()
{
__glibcxx_requires_nonempty();
c.pop_back();
}
如以vector支持stack可定义: stack<int,vector<int>> intStack;
是否支持迭代器:
只有顺序容器和关联容器支持迭代器遍历,各容器支持的迭代器的类别如下:
容器 | 支持的迭代器类别 | 说明 |
vector | 随机访问 | 一种随机访问的数组类型,提供了对数组元素进行快速随机访问以及在序列尾部进行快速的插入和删除操作的功能。可以再需要的时候修改其自身的大小 |
deque | 随机访问 | 一种随机访问的数组类型,提供了序列两端快速进行插入和删除操作的功能。可以再需要的时候修改其自身的大小 有push_back()方法,跟vector差不多,比vector多了个pop_front,push_front方法 |
list | 双向 | 一种不支持随机访问的数组类型,插入和删除所花费的时间是固定的,与位置无关。 |
set | 双向 | 一种随机存取的容器,其关键字和数据元素是同一个值。所有元素都必须具有惟一值。 |
multiset | 双向 | 一种随机存取的容器,其关键字和数据元素是同一个值。可以包含重复的元素。 |
map | 双向 | 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个特定的关键字只能与一个元素关联。 |
multimap | 双向 | 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个关键字可以与多个数据元素关联。 |
stack | 不支持 | 适配器容器类型,用vector,deque或list对象创建了一个先进后出容器 push(),pop(),top(),size(),empty() |
queue | 不支持 | 适配器容器类型,用deque或list对象创建了一个先进先出容器 push(),pop(),front()( 不是top()) |
priority_queue | 不支持 | 适配器容器类型,用vector或deque对象创建了一个排序队列 |
参考文章:
http://www.cnblogs.com/duzouzhe/archive/2010/01/12/1645191.html
http://deepfuture.iteye.com/blog/1668266
http://www.cppblog.com/The-Moment/archive/2009/06/18/88023.html