当前位置:首页 » 《随便一记》 » 正文

C++初阶学习第十三弹——容器适配器和优先级队列的概念

10 人参与  2024年11月29日 12:09  分类 : 《随便一记》  评论

点击全文阅读


目录

一.容器适配器

1.2deque的原理介绍 

1.3deque与vector和list的比较,以及deque的缺陷

1.4为什么选择deque作为stack和queue的底层默认容器?

 stack的模拟实现

queue的模拟实现

 二.优先级队列

2.1priority_queue的使用

 三、总结


一.容器适配器

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;
queue是先进先出的特殊线性数据结构,只要具有 push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。

 虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配 器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque,比如:

1.2deque的原理介绍 

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

1.3deque与vector和list的比较,以及deque的缺陷

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作 为stack和queue的底层数据结构。

1.4为什么选择deque作为stack和queue的底层默认容器?

1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。

2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。 结合了deque的优点,而完美的避开了其缺陷。

 stack的模拟实现

#include<deque>namespace zda{template<class T, class Con = deque<T>>//template<class T, class Con = vector<T>>//template<class T, class Con = list<T>>class stack{public:stack() {}void push(const T& x) { _c.push_back(x); }void pop() { _c.pop_back(); }T& top() { return _c.back(); }const T& top()const { return _c.back(); }size_t size()const { return _c.size(); }bool empty()const { return _c.empty(); }private:Con _c;};}

queue的模拟实现

#include<deque>#include <list>namespace bite{template<class T, class Con = deque<T>>//template<class T, class Con = list<T>>class queue{public:queue() {}void push(const T& x) { _c.push_back(x); }void pop() { _c.pop_front(); }T& back() { return _c.back(); }const T& back()const { return _c.back(); }T& front() { return _c.front(); }const T& front()const { return _c.front(); }size_t size()const { return _c.size(); }bool empty()const { return _c.empty(); }private:Con _c;};}

 二.优先级队列

2.1priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成 堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意: 默认情况下priority_queue是大堆。

#include <iostream>#include <queue>#include <vector>using namespace std; int main() {    // 创建一个存储int类型元素的优先级队列    priority_queue<int> pq;     // 向队列中添加元素    pq.push(1);    pq.push(3);    pq.push(2);    pq.push(5);    pq.push(1);     // 输出队列中的元素,并观察优先级    while (!pq.empty()) {        cout << pq.top() << " ";        pq.pop();    }    cout << endl;     return 0;}

 

默认情况下,priority_queue是大堆, 如果要创建小堆,将第三个模板参数换成greater比较方式

#include<iostream>#include <vector>#include <queue>#include <functional>   using namespace std;void TestPriorityQueue(){// 默认情况下,创建的是大堆,其底层按照小于号比较vector<int> v{ 3,2,7,6,0,4,1,9,8,5 };priority_queue<int> q1;for (auto& e : v)q1.push(e);cout << q1.top() << endl;// 如果要创建小堆,将第三个模板参数换成greater比较方式priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl;}int main(){TestPriorityQueue();// greater算法的头文件}

 

 三、总结

容器适配器大致的内容就讲到这里,请大佬们多多支持!


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/193842.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1