适配器
容器适配器,其就是将不适用的序列式容器(包括 vector、deque 和 list)变得适用。
STL 提供了 3 种容器适配器,分别为 stack 栈适配器、queue 队列适配器以及 priority_queue 优先权队列适配器。
基础容器筛选条件 | 默认使用的基础容器 | |
---|---|---|
stack | 基础容器需包含以下成员函数:empty()、size()、back()、push_back()、pop_back()满足条件的基础容器有 vector、deque、list。 | deque |
queue | 基础容器需包含以下成员函数:empty()、size()、front()、back()、push_back()、pop_front()满足条件的基础容器有 deque、list。 | deque |
priority_queue | 基础容器需包含以下成员函数:empty()、size()、front()、push_back()、pop_back()满足条件的基础容器有vector、deque。 |
1. stack容器
1.1 stack容器的创建
<T>>(其中 T 为存储元素的类型,Container 表示底层容器的类型)的形式位于<stack>
#include <stack>
using namespace std;
创建 stack 适配器,大致分为如下几种方式:
std::stack<int> values;
- 定义一个使用 list 基础容器的 stack 适配器:
std::stack<std::string, std::list<int>> values;
- 用一个 stack 适配器来初始化另一个 stack 适配器,只要它们存储的元素类型以及底层采用的基础容器类型相同即可:
std::list<int> values {1, 2, 3};
std::stack<int,std::list<int>> my_stack (values);
- 还可以用一个 stack 适配器来初始化另一个 stack 适配器,只要它们存储的元素类型以及底层采用的基础容器类型相同即可:
std::list<int> values{ 1, 2, 3 };
std::stack<int, std::list<int>> my_stack1(values);
std::stack<int, std::list<int>> my_stack=my_stack1;
//std::stack<int, std::list<int>> my_stack(my_stack1);
1.2 stack容器支持的成员函数
功能 | |
---|---|
empty() | 当 stack 栈中没有元素时,该成员函数返回 true;反之,返回 false。 |
size() | 返回 stack 栈中存储元素的个数。 |
top() | 返回一个栈顶元素的引用,类型为 T&。如果栈为空,程序会报错。 |
push(const T& val) | 先复制 val,再将 val 副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。 |
push(T&& obj) | 以移动元素的方式将其压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。 |
pop() | 弹出栈顶元素。 |
emplace(arg...) | arg... 可以是一个参数,也可以是多个参数,但它们都只用于构造一个对象,并在栈顶直接生成该对象,作为新的栈顶元素。 |
swap(stack<T> & other_stack) |
2. queue容器
2.1 queue容器的创建
<T>>(其中 T 为存储元素的类型,Container 表示底层容器的类型)的形式位于<queue>
#include <queue>
using namespace std;
创建queue 适配器,大致分为如下几种方式:
std::queue<int> values;
- 也可以手动指定 queue 容器适配器底层采用的基础容器类型:合条件的序列式容器仅有 deque 和 list
std::queue<int, std::list<int>> values;
std::deque<int> values{1,2,3};
std::queue<int> my_queue(values);
std::deque<int> values{1,2,3};
std::queue<int> my_queue1(values);
std::queue<int> my_queue(my_queue1);
// 或者使用
// std::queue<int> my_queue = my_queue1;
2.2 queue容器支持的成员函数
功能 | |
---|---|
empty() | 如果 queue 中没有元素的话,返回 true。 |
size() | 返回 queue 中元素的个数。 |
front() | 返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。 |
back() | 返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。 |
push(const T& obj) | 在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。 |
emplace() | 在 queue 的尾部直接添加一个元素。 |
push(T&& obj) | 以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。 |
pop() | 删除 queue 中的第一个元素。 |
swap(queue<T> &other_queue) |
和 stack 一样,queue 也没有迭代器,因此访问元素的唯一方式是遍历容器,通过不断移除访问过的元素,去访问下一个元素。
3. priority_queue容器
priority_queue 容器适配器为了保证每次从队头移除的都是当前优先级最高的元素,每当有新元素进入,它都会根据既定的排序规则找到优先级最高的元素,并将其移动到队列的队头。同样,当 priority_queue 从队头移除出一个元素之后,它也会再找到当前优先级最高的元素,并将其移动到队头。
3.1 queue容器的创建
priority_queue 容器适配器的定义如下:
template <typename T,
typename Container=std::vector<T>,
typename Compare=std::less<T> >
class priority_queue{
//......
}
-
typename T:指定存储元素的具体类型;
-
typename Container:指定 priority_queue 底层使用的基础容器,默认使用 vector 容器。
- typename Compare:指定容器中评定元素优先级所遵循的排序规则,默认使用
std::less<T>
,按照元素值从大到小进行排序,还可以使用std::greater<T>
。
- 创建一个空的 priority_queue 容器适配器,第底层采用默认的 vector 容器,排序方式也采用默认的 std::less<T> 方法:
std::priority_queue<int> values;
// 使用普通数组
int values[]{4,1,3,2};
std::priority_queue<int>copy_values(values,values+4);//{4,2,3,1}
// 使用序列式容器
std::array<int,4>values{ 4,1,3,2 };
std::priority_queue<int>copy_values(values.begin(),values.end());//{4,2,3,1}
int values[]{ 4,1,2,3 };
std::priority_queue<int, std::deque<int>, std::greater<int> >copy_values(values, values+4); // {1,3,2,4}
2.2 priority_queue容器支持的成员函数
功能 | |
---|---|
empty() | 如果 priority_queue 为空的话,返回 true;反之,返回 false。 |
size() | 返回 priority_queue 中存储元素的个数。 |
top() | 返回 priority_queue 中第一个元素的引用形式。 |
push(const T& obj) | 根据既定的排序规则,将元素 obj 的副本存储到 priority_queue 中适当的位置。 |
push(T&& obj) | 根据既定的排序规则,将元素 obj 移动存储到 priority_queue 中适当的位置。 |
emplace(Args&&... args) | Args&&... args 表示构造一个存储类型的元素所需要的数据(对于类对象来说,可能需要多个数据构造出一个对象)。此函数的功能是根据既定的排序规则,在容器适配器适当的位置直接生成该新元素。 |
pop() | 移除 priority_queue 容器适配器中第一个元素。 |
swap(priority_queue<T>& other) |
和 queue 一样,priority_queue 也没有迭代器,因此访问元素的唯一方式是遍历容器,通过不断移除访问过的元素,去访问下一个元素。
4. STL distance()函数
4.1 distance概述
distance() 函数用于计算两个迭代器表示的范围内包含元素的个数,其语法格式如下:
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type distance (InputIterator first, InputIterator last);
[first, last)
范围内包含的元素的个数。
注意,first 和 last 的迭代器类型,直接决定了 distance() 函数底层的实现机制:
-
当 first 和 last 为随机访问迭代器时,distance() 底层直接采用 last - first 求得 [first, last) 范围内包含元素的个数,其时间复杂度为
O(1)
常数阶; -
当 first 和 last 为非随机访问迭代器时,distance() 底层通过不断执行 ++first(或者 first++)直到 first==last,由此来获取 [first, last) 范围内包含元素的个数,其时间复杂度为
O(n)
线性阶。
<iterator>
#include <iterator>
using namespace std;
另外,distance() 函数定义在<iterator>
#include <iostream> // std::cout
#include <iterator> // std::distance
#include <list> // std::list
using namespace std;
int main() {
// 创建一个空 list 容器
list<int> mylist;
// 向空 list 容器中添加元素 0~9
for (int i = 0; i < 10; i++) {
mylist.push_back(i);
}
// 指定 2 个双向迭代器,用于执行某个区间
list<int>::iterator first = mylist.begin();//指向元素 0
list<int>::iterator last = mylist.end();//指向元素 9 之后的位置
// 获取 [first,last) 范围内包含元素的个数
cout << "distance() = " << distance(first, last);
return 0;
}
4.1 distance成员函数
功能 | |
---|---|
advance(it, n) | it 表示某个迭代器,n 为整数。该函数的功能是将 it 迭代器前进或后退 n 个位置。 |
distance(first, last) | first 和 last 都是迭代器,该函数的功能是计算 first 和 last 之间的距离。 |
begin(cont) | cont 表示某个容器,该函数可以返回一个指向 cont 容器中第一个元素的迭代器。 |
end(cont) | cont 表示某个容器,该函数可以返回一个指向 cont 容器中最后一个元素之后位置的迭代器。 |
prev(it) | it 为指定的迭代器,该函数默认可以返回一个指向上一个位置处的迭代器。注意,it 至少为双向迭代器。 |
next(it) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!