STL容器适配器
STL容器适配器
容器适配器指封装了序容列容器中提供了一些功能,称为适配器类。
适配器 | 头文件 | 封装 | 特点 |
---|---|---|---|
stack | <stack> | deque<T> | LIFO |
queue | <queue> | deque<T> | FIFO |
priority_queue | <queue> | vector<T> | 默认对元素进行排序,保证最大的元素在队列头 |
1.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 |
将两个 stack 适配器中的元素进行互换,需要注意的是,进行互换的 2 个 stack 适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。 |
初始化
stack<int> val;
stack<int,list<int> > val;//s
通过这种方式,指定第二个参数,stack<T,Container=deque<T>>可以使用出deque容器之外的其它序列容器,只需要支持empty()
、size()
、back()
、push_back()
、pop_back()
这 5 个成员函数即可,如果不指定默认采用deque实现
2.queue
queue 容器适配器以模板类 queue<T,Container=deque<T>>(其中 T 为存储元素的类型,Container 表示底层容器的类型)
成员函数 | 功能 |
---|---|
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 |
将两个 queue 容器适配器中的元素进行互换,需要注意的是,进行互换的 2 个 queue 容器适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。 |
3.priority_queue
priority_queue也采用队列结构存储元素,但存储顺序是按照元素大小来排的,每个优先队列初始化的时候都有一种排序规则 ,根据该规则确定了出队的优先顺序。
template <typename T,//指定存储元素的具体类型;
typename Container=std::vector<T>, //指定 priority_queue 底层使用的基础容器,默认使用 vector 容器
typename Compare=std::less<T> >//排序规则,less<T>从大到小,greater<T>从小到大,也可以自定义排序规则
int val[]{3,1,2};
vector<int> arr{3,1,2};
priority_queue<int> q(val,val+3);//使用普通数组初始化
priority_queue<int,deque<int>,greater<int>> q(arr.begin(),arr.end());//使用vector数组初始化
成员函数 | 功能 |
---|---|
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 |
将两个 priority_queue 容器适配器中的元素进行互换,需要注意的是,进行互换的 2 个 priority_queue 容器适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。 |
自定义排序规则:
仿函数
class cmp
{
public:
//重载 () 运算符
bool operator()(T a, T b)
{
return a > b;
}
};
当 priority_queue 容器适配器中存储的数据类型为结构体或者类对象(包括 string 类对象)时,还可以通过重载其 > 或者 < 运算符,间接实现自定义排序规则的目的
std::less<T> 的底层实现代码为
template <typename T>
struct less {
//定义新的排序规则
bool operator()(const T &_lhs, const T &_rhs) const {
return _lhs < _rhs;
}
};
//重载<
bool operator < (const node &a, const node &b) {
if (a.x > b.x) return 1;
else if (a.x == b.x)
if (a.y >= b.y) return 1;
return 0;
}
也可以以友元函数或者成员函数的方式重载 > 或者 < 运算符。需要注意的是,以成员函数的方式重载 > 或者 < 运算符时,该成员函数必须声明为 const 类型,且参数也必须为 const 类型.
priority_queue底层实现
该容器采用堆数据结构存储结构,底层采用vector实现,保证优先级高的元素在队头,虽然不使用堆结构,通过编写算法调整 vector 或者 deque 容器中存储元素的次序,但执行效率通常没有使用堆结构高。
STL对堆存储结构的函数<algorithm>
函数 | 功能 |
---|---|
make_heap(first,last,comp) | 选择位于 [first,last) 区域内的数据,并根据 comp 排序规则建立堆,其中 first 和 last 可以是指针或者迭代器,默认是建立大顶堆。 |
push_heap(first,last,comp) | 当向数组或容器中添加数据之后,此数据可能会破坏堆结构,该函数的功能是重建堆。 |
pop_heap(first,last,comp) | 将位于序列头部的元素(优先级最高)移动序列尾部,并使[first,last-1] 区域内的元素满足堆存储结构。 |
sort_heap(first,last,comp) | 对 [first,last) 区域内的元素进行堆排序,将其变成一个有序序列。 |
is_heap_until(first,last,comp) | 发现[first,last)区域内的最大堆。 |
is_heap(first,last,comp) | 检查 [first,last) 区域内的元素,是否为堆结构。 |