在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器。很简单,容器就是保存其它对象的对象。
STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。
顺序性容器 :一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。
顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。这个位置和 元素本身无关,而和操作的时间和地点有关,顺序性容器不会根据元素的特点排序而是直接保存了元素操作时的逻辑顺序。比如我们一次性对一个顺序性容器追加三个元素,这三个元素在容器中的相对位置和追加时的逻辑次序是一致的。
关联式容器 :非线性的树结构,更准确的说是二叉树结构。
容器适配器 :是一个比较抽象的概念。
C++的 解释是:适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器是让一种已存在的容器类型采用另一种不同的抽象类型的工作方式来实现的一种机 制。其实仅是发生了接口转换。那么你可以把它理解为容器的容器,它实质还是一个容器,只是他不依赖于具体的标准容器类型,可以理解是容器的模版。或者把它 理解为容器的接口,而适配器具体采用哪种容器类型去实现,在定义适配器的时候可以由你决定。
下表列出STL 定义的三类容器所包含的具体容器类
标准容器类 | 特点 |
---|---|
顺序性容器 | |
vector | 从后面快速的插入与删除,直接访问任何元素 |
deque | 从前面或后面快速的插入与删除,直接访问任何元素 |
list | 双链表,从任何地方快速插入与删除 |
关联容器 | |
set | 快速查找,不允许重复值 |
multiset | 快速查找,允许重复值 |
map | 一对多映射,基于关键字快速查找,不允许重复值 |
multimap | 一对多映射,基于关键字快速查找,允许重复值 |
容器适配器 | |
stack | 后进先出 |
queue | 先进先出 |
priority_queue | 最高优先级元素总是第一个出列 |
栈stack、队列queue 和 优先级 priority_queue
适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。
STL 中提供的三种适配器可以由某一种顺序容器去实现。默认下stack 和queue 基于deque 容器实现,priority_queue 则基于vector 容器实现。当然在创建一个适配器时也可以指定具体的实现容器,创建适配器时在第二个参数上指定具体的顺序容器可以覆盖适配器的默认实现。
由于适配器的特点,一个适配器不是可以由任一个顺序容器都可以实现的。
栈stack 的特点是后进先出,所以它关联的基本容器可以是任意一种顺序容器,因为这些容器类型结构都可以提供栈的操作有求,它们都提供了push_back 、pop_back 和back 操作;
队列queue 的特点是先进先出,适配器要求其关联的基础容器必须提供pop_front 操作,因此其不能建立在vector 容器上;
优先级队列priority_queue 适配器要求提供随机访问功能,因此不能建立在list 容器上。
stack是一种先进后出的数据结构,它只要一个出口
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
入栈 -------- push()
出栈 -------- pop()
构造函数:
stack stk;
// stack采用模板类实现,stack对象的默认构造stack(const stack& stk);
// 拷贝构造函数赋值操作:
stack& operator=(const stack& stk);
数据存取:
push(elem);
// 向栈顶添加元素pop();
// 从栈顶移除第一个元素top();
// 返回栈顶元素大小操作:
empty();
// 判断是否为空size();
// 返回栈的大小示例:
#include
#include
using namespace std;
void test()
{
// 创建栈容器,后进先出
stack<int> s;
// 入栈
s.push(10);
s.push(20);
s.push(30);
s.push(40);
while(!s.empty())
{
// 输出栈顶元素
cout << "栈顶元素: " << s.top() << endl;
// 出栈
s.pop();
}
cout << "栈的大小为:" << s.size() << endl;
}
int main()
{
test();
return 0;
}
push
pop
构造函数:
queue que;
//queue采用模板类实现,默认构造queue(const queue& que);
// 拷贝构造函数赋值操作:
queue& operator=(const queue& que);
数据存取:
push(elem);
// 往队尾添加元素pop();
// 从队头移除第一个元素back();
// 返回最后一个元素front();
// 返回第一个元素大小操作:
empty();
// 判断是否为空size();
// 返回大小示例:
//先进先出
queue<int> q;
// 入队,往队尾添加元素
q.push(10);
q.push(20);
q.push(30);
q.push(40);
// 出队,队顶删除元素
q.pop(); // 删掉了10
if( !q.empty() )
{
cout << q.front() << endl; // 20
cout << q.back() << endl; // 40
cout << q.size() << endl; // 3
}