文章目录
一、容器
1. 定义
在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器。很简单,容器就是保存其它对象的对象。
2. 好处
- “容器类是一种对特定代码重用问题的良好的解决方案”
- 容器可以自行扩展。它不需要你预先告诉它你要存储多少对象,只要你创建一个容器对象,并合理的调用它所提供的方法,所有的处理细节将由容器来自身完成。它可以为你申请内存或释放内存,并且用最优的算法来执行您的命令。
3. 通用容器的分类
STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。
顺序性容器 :一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。
顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。这个位置和 元素本身无关,而和操作的时间和地点有关,顺序性容器不会根据元素的特点排序而是直接保存了元素操作时的逻辑顺序。比如我们一次性对一个顺序性容器追加三个元素,这三个元素在容器中的相对位置和追加时的逻辑次序是一致的。
关联式容器 :非线性的树结构,更准确的说是二叉树结构。
- 各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。
- 它是以键值的方式来保存数据,就是说它能把关键字和值关联起来保存,而顺序性容器只能保存一种(可以认为它只保存关键字,也可以认为它只保存值)。这在下面具体的容器类中可以说明这一点
容器适配器 :是一个比较抽象的概念。
C++的 解释是:适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器是让一种已存在的容器类型采用另一种不同的抽象类型的工作方式来实现的一种机 制。其实仅是发生了接口转换。那么你可以把它理解为容器的容器,它实质还是一个容器,只是他不依赖于具体的标准容器类型,可以理解是容器的模版。或者把它 理解为容器的接口,而适配器具体采用哪种容器类型去实现,在定义适配器的时候可以由你决定。
4. 总结图
下表列出STL 定义的三类容器所包含的具体容器类
标准容器类 | 特点 |
---|---|
顺序性容器 | |
vector | 从后面快速的插入与删除,直接访问任何元素 |
deque | 从前面或后面快速的插入与删除,直接访问任何元素 |
list | 双链表,从任何地方快速插入与删除 |
关联容器 | |
set | 快速查找,不允许重复值 |
multiset | 快速查找,允许重复值 |
map | 一对多映射,基于关键字快速查找,不允许重复值 |
multimap | 一对多映射,基于关键字快速查找,允许重复值 |
容器适配器 | |
stack | 后进先出 |
queue | 先进先出 |
priority_queue | 最高优先级元素总是第一个出列 |
二、容器适配器
1. 定义
栈stack、队列queue 和 优先级 priority_queue
适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。
STL 中提供的三种适配器可以由某一种顺序容器去实现。默认下stack 和queue 基于deque 容器实现,priority_queue 则基于vector 容器实现。当然在创建一个适配器时也可以指定具体的实现容器,创建适配器时在第二个参数上指定具体的顺序容器可以覆盖适配器的默认实现。
由于适配器的特点,一个适配器不是可以由任一个顺序容器都可以实现的。
2. 特点
栈stack 的特点是后进先出,所以它关联的基本容器可以是任意一种顺序容器,因为这些容器类型结构都可以提供栈的操作有求,它们都提供了push_back 、pop_back 和back 操作;
队列queue 的特点是先进先出,适配器要求其关联的基础容器必须提供pop_front 操作,因此其不能建立在vector 容器上;
优先级队列priority_queue 适配器要求提供随机访问功能,因此不能建立在list 容器上。
三、stack容器
1. stack基本概念
stack是一种先进后出的数据结构,它只要一个出口
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
入栈 -------- push()
出栈 -------- pop()
2. stack常用接口
构造函数:
stack<T> stk;
// stack采用模板类实现,stack对象的默认构造stack(const stack& stk);
// 拷贝构造函数
赋值操作:
stack& operator=(const stack& stk);
数据存取:
push(elem);
// 向栈顶添加元素pop();
// 从栈顶移除第一个元素top();
// 返回栈顶元素
大小操作:
empty();
// 判断是否为空size();
// 返回栈的大小
示例:
#include<iostream>
#include<stack>
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;
}
四、queue容器
1. queue基本概念
queue是一种先进先出的数据结构,它有两个出口
- 队列容器允许从一端新增元素,从另一端移除元素
- 队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为
- 队列中进数据称为 — 入队
push
- 队列中出数据称为 — 出队
pop
2. queue常用接口
构造函数:
queue<T> 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
}