【c++】——栈or队列or优先级队列

目录

🎓容器适配器

🎓Stack栈

🚩Stack的介绍

🚩Stack的基本使用 

🚩Stack底层实现

🎓queue队列

🚩queue的介绍

🚩queue的基本使用

🚩queue的底层实现

🎓priority_queue优先级队列

🚩priority_queue的介绍

✅简单介绍一下仿函数

 🚩priority_queue的基本使用

🚩priority_queue的底层实现

✅仿函数的使用


🎓容器适配器

 容器适配器是一个封装了序列容器的一个类模板,它在一般的序列容器的基础上提供了一些不同的功能。之所以称为容器适配器,是因为它是适配容器来提供其它不一样的功能。通过对应的容器和成员函数来实现我们需要的功能。

        下面介绍了三个容器适配器:statk<T>,queue<T>,priority_queue<T>

 注意:容器适配器都不存在迭代器。

        如果没有为stack,queue指定容器,默认使用deque作为默认容器。priority_queue容器默认使用vector作为默认容器。

🎓Stack栈

🚩Stack的介绍


以下是stack的成员函数 

string、vector、list都是容器,而stack和queue 是容器适配器,发现stack和queue都没有迭代器,因为stack要保证后进先出(LIFO),queue要保证先进先出(FIFO)所以其实它们不需要迭代器。


🚩Stack的基本使用 

这下面是stack接口函数,使用是简单的,主要应用的场景。

#include <iostream>
using namespace std;
#include <stack>//记得包头文件int main()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);st.push(6);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;return 0;
}


🚩Stack底层实现

stack就是我们数据结构学的栈,是一种操作受限制的线性表,所以它可以用链表实现,也可以用顺序表(数组)实现,不过当时C语言只实现了数组栈,因为相对而言数组的结构实现更优一些。因为数组在尾上插入删除数据的代价比较小。那传统的写法就是用一个数组或链表去写.若按C++STL库里的方式来写,就可以用适配器(配接器)模式来实现。

#pragma once
#include<vector>
#include<list>
#include<deque>namespace cl {template<class T,class Container=deque<T>>//Container缺省用deque容器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:Container _c;};void test_stack1(){//stack<int>st;stack<int, vector<int>>st;//明确给出用vector容器st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;}void test_stack2(){stack<int, list<int>>st;//明确给出用list容器st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;}
}


🎓queue队列

🚩queue的介绍

元素从队尾入队列,从对头出队列。


🚩queue的基本使用

这下面是queue接口函数,使用是简单的,主要应用的场景。

使用queue需要包含头文件#include<queue>,queue容器适配器没有迭代器

int main()
{queue<int>q;q.push(1);q.push(2);q.push(3);q.push(4);cout << q.front() << endl;//队头元素cout << q.back() << endl;//队尾元素cout << q.size() << endl;//队长while (!q.empty()){cout << q.front() << " ";q.pop();}return 0;
}


🚩queue的底层实现

因为queue存在头删和尾插,因此使用vector容器来封装效率太低,头删需要挪动数据,并且vector并没有提供pop_front(),因为效率太低。

#pragma once
#include<queue>
#include<list>
namespace cl {template <class T,class Container=deque<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:Container _c;};void test_queue(){queue<int>q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}void test_queue2(){queue<int,list<int>>q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}
}


🎓priority_queue优先级队列

🚩priority_queue的介绍

默认形成大堆。优先队列使用仿函数来控制生成大根堆还是生成小根堆。

✅简单介绍一下仿函数

 仿函数(Functor)又称为函数对象(Function Object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载 operator() 运算符。因为调用仿函数,实际上就是通过类对象调用重载后的 operator() 运算符。仿函数是一个类,只是使用起来像函数。等下模拟实现时就知道了。

 🚩priority_queue的基本使用

优先队列默认使用vector作为存储数据的容器,在容器的基础上使用堆算法,将vector中的元素调整成一个堆结构。

注意:优先队列就是一个堆,在使用堆的地方都可以使用优先队列。默认生成大根堆,头文件也是#include<queue>

//默认调整大堆
int main()
{priority_queue<int>pq;pq.push(1);pq.push(2);pq.push(5);pq.push(3);pq.push(0);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;return 0;
}//小堆
int main()
{priority_queue<int,vector<int>,greater<int>>pq;pq.push(1);pq.push(2);pq.push(5);pq.push(3);pq.push(0);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;return 0;
}


🚩priority_queue的底层实现

   回顾一下堆的插入与删除操作。

  •         堆的插入:在堆尾插入数据,再向上调整成堆。
  •         堆的删除:将堆顶元素和对尾元素交换,再向下调整成堆。

#pragma once
#include<vector>
#include<deque>
namespace cl {template <class T,class Container=vector<T>>class priority_queue {void AdjustDown(int parent){int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _con[child] < _con[child + 1]){child++;}if (_con[parent] < _con[child]){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void Adjustup(int child){int parent = (child - 1) / 2;while (child >0){if (_con[parent]<_con[child]){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:priority_queue() {}template <class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){_con.push_back(*first);++first;}//建堆for (int i = (_con.size - 1 - 1) / 2; i >= 0; i--){AdjustDown(i);}}bool empty() {return _con.empty();}size_t size() {return _con.size();}T& top() {return _con.front();}const T& top()const {return _con.front();}void push(const T& val) {_con.push_back(val);Adjustup(_con.size() - 1);}void pop() {swap(_con[0], _con[_con.size() - 1]);//少一个元素是size减减,交换后,直接删除最后一个元素_con.pop_back();AdjustDown(0);}private:Container _con;};void priority_queue1(){priority_queue<int>pq;pq.push(1);pq.push(3);pq.push(4);pq.push(5);while(!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;}
}

✅仿函数的使用

仿函数:优先队列通过仿函数来实现建立大根堆还是小根堆。

调整建立大根堆还是小根堆,只需要改变调整函数。父亲结点与孩子结点比较时的大于小于号。怎么通过仿函数来实现呢?

调整函数如何修改

#pragma once
#include<vector>
#include<deque>
template<class T>
class Less {
public:bool operator()(const T& x, const T& y){return x < y;}
};
template<class T>
class Greater {
public:bool operator()(const T& x, const T& y){return x > y;}
};
namespace cl {template <class T,class Container=vector<T>,class Compare=Less<T>>class priority_queue {void AdjustDown(int parent){Compare com;int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){child++;}if (com(_con[parent],_con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void Adjustup(int child){Compare com;int parent = (child - 1) / 2;while (child >0){if (com(_con[parent],_con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:priority_queue() {}template <class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){_con.push_back(*first);++first;}//建堆for (int i = (_con.size - 1 - 1) / 2; i >= 0; i--){AdjustDown(i);}}bool empty() {return _con.empty();}size_t size() {return _con.size();}T& top() {return _con.front();}const T& top()const {return _con.front();}void push(const T& val) {_con.push_back(val);Adjustup(_con.size() - 1);}void pop() {swap(_con[0], _con[_con.size() - 1]);//少一个元素是size减减,交换后,直接删除最后一个元素_con.pop_back();AdjustDown(0);}private:Container _con;};void priority_queue1(){priority_queue<int>pq;//默认调成大根堆pq.push(1);pq.push(3);pq.push(4);pq.push(5);while(!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;priority_queue<int, vector<int>, greater<int>> pq2;//小根堆pq2.push(1);pq2.push(3);pq2.push(4);pq2.push(5);while (!pq2.empty()){cout << pq2.top() << " ";pq2.pop();}cout << endl;}
}


一帆风顺不现实,祝你挫折少一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633728.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】C++的IO流

一、C语言的输入与输出 C 语言中我们用到的最频繁的输入输出方式就是 scanf () 与 printf()。 scanf()&#xff1a;从标准输入设备&#xff08;键盘&#xff09;读取数据&#xff0c;并将值存放在变量中。printf()&#xff1a;将指定的文字/字符串输出到标准输出设备&#xff…

Java如何做到无感知刷新token含示例代码(值得珍藏)

1. 前言 在系统页面进行业务操作时&#xff0c;有时会突然遇到应用闪退&#xff0c;并被重定向至登录页面&#xff0c;要求重新登录。此问题的出现&#xff0c;通常与系统中用于存储用户ID和token信息的Redis缓存有关。具体来说&#xff0c;这可能是由于token过期所导致的身份…

容器部署的nextcloud配置onlyoffice时开启密钥

容器部署的nextcloud配置onlyoffice时开启密钥 配置 进入onlyoffice容器 docker exec -it 容器id bash编辑配置vi /etc/onlyoffice/documentserver/local.json enable设置为true&#xff0c;并配置secret 重启容器&#xff0c;并将配置的密钥填入nextcloud密钥页面 docker r…

复杂字幕特效SDK,重塑视频字幕新体验

字幕特效已经成为了提升视频品质、增强观众体验的重要手段。美摄科技作为行业领先的技术提供商&#xff0c;近期推出的复杂字幕特效SDK&#xff0c;更是引领了这一领域的创新潮流。 美摄科技复杂字幕特效SDK&#xff0c;不仅具备了电影级别的字幕功能&#xff0c;更实现了众多…

【全网最全】2024华数杯国际赛B题成品论文50页+1-4问高质量代码+完整数据集+建模过程+保姆级教学

基于数据分析下的光伏发电 摘 要&#xff08;完整版在文末&#xff09; 根据最新数据&#xff0c;中国的总发电量超过20万亿千瓦时&#xff0c;总体排名世界第一&#xff0c;而光伏发电是一种重要的可再生能源&#xff0c;可以将太阳能转化为电能可以减少对传统能源的依赖&…

VBA窗体跟随活动单元格【简易版】(2/2)

上一篇博客&#xff08;文章连接如下&#xff09;中使用工作表事件Worksheet_SelectionChange实现了窗体跟随活动单元格的动态效果。 VBA窗体跟随活动单元格【简易版】(1/2) 为了在用户滚动工作表窗体之后仍能够实现跟随效果&#xff0c;需要使用Application.Windows(1).Visibl…

归并排序详解

目录 ​&#x1f4a1;基本思想 &#x1f4a1;图文介绍 &#x1f4a1;动图演示 &#x1f4a1;过程解释 &#x1f4a1;代码实现 &#x1f4a1;递归实现 &#x1f4a1;非递归实现 &#x1f4a1;总结 &#x1f4a1;基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是…

数据结构--串

本文为复习的草稿笔记&#xff0c;&#xff0c;&#xff0c;有点乱 1. 串的基本概念和基本操作 串是由零个或多个字符组成的有限序列 2. 串的存储结构 3.串的应用 模式匹配 BF算法&#xff08;简单匹配算法 穷举法 算法思路&#xff1a;从子串的每一个字符开始依次与主串…

深耕文档型数据库12载,SequoiaDB再开源

1月15日&#xff0c;巨杉数据库举行SequoiaDB新特性及开源项目发布活动。本次活动回顾了巨杉数据库深耕JSON文档型数据库12年的发展历程与技术演进&#xff0c;全面解读了SequoiaDB包括在高可用、安全、实时、易用性四个方向的技术特性&#xff0c;宣布了2024年面向技术社区的开…

无法打开浏览器开发者工具的可能解决方法

网页地址: https://jx.xyflv.cc/?url视频地址url 我在抖音里面抓了一个视频地址, 获取到响应的json数据, 找到里面的视频地址信息 这个网站很好用: https://www.jsont.run/ 可以使用js语法对json对象操作, 找到所有视频的url地址 打开网页: https://jx.xyflv.cc/?urlhttps:…

【Linux C | 文件操作】目录相关操作 | mkdir、rmdir、opendir、readdir、closedir、getcwd、chdir

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【LeetCode】栈精选9题

目录 1. 删除字符串中的所有相邻重复项&#xff08;简单&#xff09; 2. 逆波兰表达式&#xff08;中等&#xff09; 3. 基本计算器 II&#xff08;中等&#xff09; 4. 字符串解码&#xff08;中等&#xff09; 5. 验证栈序列&#xff08;中等&#xff09; 6. 小行星碰撞…

新能源汽车智慧充电桩方案:基于视频监控的可视化智能监管平台

一、方案概述 TSINGSEE青犀&触角云新能源汽车智慧充电桩方案围绕互联网、物联网、车联网、人工智能、视频技术、大数据、4G/5G等技术&#xff0c;结合云计算、移动支付等&#xff0c;实现充电停车一体化、充电桩与站点管理等功能&#xff0c;达到充电设备与站点的有效监控…

有效防范网络风险的关键措施

在数字化时代&#xff0c;企业面临着日益复杂和频繁的网络风险。提高员工的网络安全意识是防范网络威胁的关键一步。本文将探讨企业在提升网络安全意识方面可以采取的措施&#xff0c;以有效预防潜在的网络风险。 1. 开展网络安全培训&#xff1a;企业应定期组织网络安全培训&…

vue中内置指令v-model的作用和常见使用方法介绍以及在自定义组件上支持

文章目录 一、v-model是什么二、什么是语法糖三、v-model常见的用法1、对于输入框&#xff08;input&#xff09;&#xff1a;2、对于复选框&#xff08;checkbox&#xff09;&#xff1a;3、对于选择框&#xff08;select&#xff09;&#xff1a;4、对于组件&#xff08;comp…

java基本算法

1.链表 链表用来存储数据&#xff0c;由一系列的结点组成。这些结点的物理地址不一定是连续的&#xff0c;即可能连续&#xff0c;也可能不连续&#xff0c;但链表里的结点是有序的。一个结点由数据的值和下一个数据的地址组成。一个链表内的数据类型可以是多种多样的。数组也是…

中霖教育:2024年一建、二建考试问题整理

报名、考试时间&#xff1a; ①一建&#xff1a;报名时间6月;考试时间9月上旬 ②二建&#xff1a;报名时间1-3月份;考试时间6月 考试科目&#xff1a; ①一级建造师考试科目一共有四门,依次是《建设工程经济》、《建设工程法规及相关知识》、《建设工程项目管理》、《专业工…

Vue以弹窗形式实现导入功能

目录 前言正文 前言 由于个人工作原因&#xff0c;偏全栈&#xff0c;对于前端的总结还有些初出茅庐&#xff0c;后续会进行规整化的总结 对应的前端框架由&#xff1a;【vue】avue-crud表单属性配置&#xff08;表格以及列&#xff09; 最终实现的表单样式如下&#xff1a;…

深入浅出AI落地应用分析:国内Top10应用

接下来会每周集中体验一些通用或者垂直的AI落地应用&#xff0c;主要以一些全球或者国外国内排行较前的产品为研究对象&#xff0c;「AI 产品榜&#xff1a; aicpb.com」以专题的方式在博客进行分享。 1. 文心一言 产品链接&#xff1a;https://yiyan.baidu.com/ 产品介绍&…