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 & other_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 &other_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& other) 将两个 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) 区域内的元素,是否为堆结构。
posted @ 2021-10-23 15:36  流光之中  阅读(63)  评论(0编辑  收藏  举报