STL的容器可以分为以下几个大类:
- 序列容器:vector,list,deque,string.
- 关联容器:set,multiset, map, mulmap,hash_set, hash_map, hash_multiset, hash_multimap
- 其他的杂项:stack, queue,valarray, bitset
STL各个容器的实现:
vector
内部数据结构:数组。
随机访问每个元素,所需要的时间为常量。
在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。
可动态增加或减少元素,内存管理自动完成,但程序员可以使用reserve()成员函数来管理内存。
vector的迭代器在内存重新分配时将失效(它所指向的元素在该操作的前后不再相同)。当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效;否则,指向当前元素以后的任何元素的迭代器都将失效。当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。deque
内部数据结构:数组。(访问元素、删除增加元素性质与vector相同)
可动态增加或减少元素,内存管理自动完成,不提供用于内存管理的成员函数。
增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。list
内部数据结构:双向环状链表。可双向遍历。
不能随机访问一个元素。在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。
可动态增加或减少元素,内存管理自动完成。
增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。slist
内部数据结构:单向链表。
不可双向遍历,只能从前到后地遍历。
其它的特性同list相似。stack
适配器,它可以将任意类型的序列容器转换为一个堆栈,一般使用deque作为支持的序列容器。
元素只能后进先出(LIFO)。不能遍历整个stack。queue
适配器,它可以将任意类型的序列容器转换为一个队列,一般使用deque作为支持的序列容器。
元素只能先进先出(FIFO)。不能遍历整个queue。priority_queue
适配器,它可以将任意类型的序列容器转换为一个优先级队列,一般使用vector作为底层存储方式。
只能访问第一个元素,不能遍历整个priority_queue。第一个元素始终是优先级最高的一个元素。set
键和值相等。键唯一。元素默认按升序排列。
如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。multiset
键可以不唯一。其它特点与set相同。hash_set
与set相比较,它里面的元素不一定是经过排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然跟hash函数有关)。
其它特点与set相同。hash_multiset
键可以不唯一。其它特点与hash_set相同。map
键唯一。元素默认按键的升序排列。
如果迭代器所指向的元素被删除,则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。multimap
键可以不唯一。
其它特点与map相同。hash_map
与map相比较,它里面的元素不一定是按键值排序的,而是按照所用的hash函数分派的,它能提供更快的搜索速度(当然也跟hash函数有关)。
其它特点与map相同。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();
}
可以使用任何序列式容器来支持stack,只要他们支持back(),push_back(),pop_back()等动作就行。
如以vector支持stack可定义: stack<int,vector<int>> intStack;
参考文章:
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