【C++】容器适配器,stack,queue,priority_queue详解,模拟实现

目录

1. stack和queue的介绍

1.1 stack的成员函数

1.2 queue的成员函数

1.3 stack的使用

1.4 queue的使用

1.5 Container模板参数,deque

2. priority_queue优先级队列的介绍

3. stack模拟实现

3.1 初始结构

3.2 push

3.3 pop

3.4 top

3.5 empty

3.6 size 

4. queue模拟实现

4.1 pop

4.2 front

4.3 back 

5. priority_queue模拟实现

5.1 初始结构

5.2 push

5.3 pop

5.4 top,empty,size

5.5 仿函数

5.6 仿函数第二个用法

5.7 迭代器区间构造

6. 编程题

6.1 最小栈

6.2 栈的压入、弹出

6.3 逆波兰表达式求值 


1. stack和queue的介绍

1. 模板参数有不同。

2. vector,list是自己管理数据,容器适配器是在其他容器的基础上封装实现出我要的效果。

1.1 stack的成员函数

 

1.2 queue的成员函数

1.3 stack的使用

void test1()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;
}

1.4 queue的使用

void test2()
{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;
}

1.5 Container模板参数,deque

1. 传入一个容器的模板参数,通过控制容器的行为,实现栈的效果。

2. 这就是容器适配器,你用不同的容器都能适配出栈的效果。

3. 栈和队列传入的默认容器是deque。

4. deque是双端队列,但它不是队列,因为它不要求先进先出。

5. vector不支持头插头删,list不支持随机访问,deque都支持。

6. deque擅长头尾修改。

2. priority_queue优先级队列的介绍

【接口】

【使用】

1. 不需要单独包头文件,放在queue的头文件里面。

2. 默认是大堆,top就是取堆顶的数据。

3. 插入删除是logn。

4. 降序是less,升序是greater。

void test3()
{priority_queue<int, vector<int>, greater<int>> pq;pq.push(2);pq.push(4);pq.push(7);pq.push(1);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;
}

3. stack模拟实现

3.1 初始结构

stack类需要两个模板参数,一个是数据类型,一个是容器,成员就是容器实例化的对象。 

namespace lyh
{template<typename T, typename Container = deque<T>>class stack{public:private:Container _con;};
}

3.2 push

复用容器进行尾插。

		void push(const T& val){_con.push_back(val);}

3.3 pop

复用容器进行尾删。

		void pop(){_con.pop_back();}

3.4 top

复用容器返回尾数据。

		const T& top(){_con.back();}

3.5 empty

复用容器判空。

		bool empty(){_con.empty();}

3.6 size 

复用容器返回数据个数。

		size_t size(){return _con.size();}

4. queue模拟实现

4.1 pop

pop和栈不一样,pop复用容器头删。

		void pop(){_con.pop_front();}

4.2 front

复用容器返回头数据。

		const T& front(){return _con.front();}

4.3 back 

复用容器返回尾数据。

		const T& back(){return _con.back();}

其他都和栈一样,因为栈在一端进出,队列在一端进一端出。

5. priority_queue模拟实现

5.1 初始结构

1. priority_queue最适合用vector。

2. 两个模板参数,一个是数据类型,一个是容器。

3. 成员是容器实例化的对象。

namespace lyh
{template<typename T, typename Container = vector<T>>class priority_queue{public:private:Container _con;};
}

5.2 push

1. 复用容器尾插数据。

2. 进行向上调整,保持数据的堆结构。 

		//默认大堆//向上调整void adjust_up(size_t child){size_t parent = (child - 1) / 2;while (child > 0){if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}//插入void push(const T& val){_con.push_back(val);adjust_up(_con.size() - 1);}

5.3 pop

1. pop是删除堆顶的数据,先把堆顶数据和最后一个数据交换,然后复用容器尾删。

2. 换上来的数据进行向下调整保持堆的结构。 

		//向下调整void adjust_down(size_t parent){size_t child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _con[child + 1] > _con[child]){++child;}if (_con[parent] < _con[child]){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}//删除堆顶数据void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}

5.4 top,empty,size

1. top返回第一个位置数据,empty和size复用容器即可。 

		//返回堆顶数据const T& top(){return _con[0];}//判空bool empty(){return _con.empty();}//返回数据个数size_t size(){return _con.size();}

5.5 仿函数

1. 它是一个对象,但却像函数一样使用。

2. 也可以套个模板增加适配性。

3. 功能上是为了替代函数指针。


1. 给priority加多一个仿函数的模板参数。

2. 将代码中控制大堆小堆的地方(parent和child比较的代码)替换成仿函数,这样比较符号就不会写死,根据你传入的仿函数对象决定比较方式。

template<typename T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};
template<typename T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};

		void adjust_up(size_t child){Compare cpr;size_t parent = (child - 1) / 2;while (child > 0){if (cpr(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}
		void adjust_down(size_t parent){Compare cpr;size_t child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && cpr(_con[child], _con[child+1])){++child;}if (cpr(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}

5.6 仿函数第二个用法

1. 如果传入了对象的指针,指针是内置类型无法重载比较运算符,单纯比较指针的话也不对,这时候就需要用仿函数定制对应的比较方法。

2. 比如,当优先级队列存的是对象的指针,那我们就写一个针对指针比较的仿函数,传入的是指针其实内部比较的还是对象。

5.7 迭代器区间构造

1. 传入一段迭代器区间,然后在初始化列表用容器去初始化。

2. 在将这段初始化的区间建堆。 

		template<typename InputIterator>priority_queue(InputIterator first, InputIterator last):_con(first, last){//建堆for (i = (_con.size() - 1 - 1) / 2; i >= 0; --i){adjust_down(i);}}

完整代码:Stack_Queue/Stack_Queue · 林宇恒/code-cpp - 码云 - 开源中国 (gitee.com)

6. 编程题

6.1 最小栈

链接:. - 力扣(LeetCode)

【思路】

1. 用两个栈实现找最小元素,一个栈正常入栈,另一个栈判断当入的值等于或小于自己才入栈。

2. 用两个栈作为类的成员变量。第一个是正常栈,第一个是标记最小元素的栈。

3. push,正常栈直接push,标记栈只有为空或者小于等于栈顶元素才push。

4. pop,先判断标记栈,如果两个栈的栈顶元素是相等的,那么两个栈都pop,如果不相等,那么只有正常栈pop。

5. top,取正常栈的栈顶元素。

6. getMin,取标记栈的栈顶元素。

class MinStack 
{
public:stack<int> st;stack<int> minst;void push(int val) {st.push(val);if(minst.empty() || val <= minst.top()){minst.push(val);}}void pop() {if(st.top() == minst.top()){minst.pop();}st.pop();}int top() {return st.top();}int getMin() {return minst.top();}
};

6.2 栈的压入、弹出

链接:栈的压入、弹出序列_牛客题霸_牛客网

【思路】

1. 模拟入栈出栈。

2. 首先会提供一个入栈序列和一个出栈序列,外部循环就是根据入栈序列不断入栈,每入一个数据就下标++,全部入完循环也就结束了。

3. 每次入栈一个数据,就会进行比较,如果当前栈顶数据和出栈序列一样就出栈,然后出栈序列下标++,继续比较下一个栈顶元素,直到不匹配或栈为空。

4. 入栈,然后比较,比较完继续入栈,直到入栈结束,此时如果栈不为空,那么给的出栈序列是有问题的。

    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {stack<int> st;size_t pushi = 0, popi = 0;while(pushi < pushV.size()){st.push(pushV[pushi]);++pushi;while(!st.empty() && st.top() == popV[popi]){st.pop();++popi;}}return st.empty();}

6.3 逆波兰表达式求值

链接:. - 力扣(LeetCode)

【思路】

1. 利用栈,遍历数组,

2. 如果是数字就入栈,

3. 如果是符号就出栈两个数字进行运算(要区分左右),计算完结果要入栈,

4. 遍历完之后,栈会剩下一个值就是答案。

    bool CheckOperator(const string& s){return s == "+" || s == "-" || s == "*" || s == "/"; }int calculate(int left, const string& s, int right){if(s == "+"){return left + right;}else if(s == "-"){return left - right;}else if(s == "*"){return left * right;}else {return left / right;}}int evalRPN(vector<string>& tokens) {stack<string> st;for(int i=0; i<tokens.size(); i++){if(!CheckOperator(tokens[i])){st.push(tokens[i]);}else{int right = stoi(st.top());st.pop();int left = stoi(st.top());st.pop();int cal = calculate(left, tokens[i], right);st.push(to_string(cal));}}return stoi(st.top());}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C++笔试强训15、16、17

文章目录 笔试强训15一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训16一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训17一、选择题1-5题6-10题 二、编程题题目一题目二 笔试强训15 一、选择题 1-5题 共有派生下&#xff0c;派生类的成员函数只能访问基类的…

揭秘智能派单流程:如何利用AI实现高效的自动化任务分配?

前言 在当今的企业管理和服务行业中&#xff0c;高效的工作分配与任务管理是提升企业竞争力的重要因素。智能派单流程通过结合先进的算法和人工智能技术&#xff0c;实现了工作任务的自动化分配和优化管理&#xff0c;不仅帮助企业提升了工作效率&#xff0c;降低了运营成本&a…

Kubernetes强制删除terminating状态的namespace

Kubernetes中的Namespace处于Terminating状态并且常规删除不起作用。 1.Namespace长时间处于Terminating状态往往是因为某些finalizers阻止了它的删除。 kubectl get namespace <namespace-name> -o json > namespace.json 2.编辑生成的 namespace.json文件&#xff…

在 Vue 3 中实现“折叠”与“展开”文本内容

偶然间遇到一个场景&#xff0c;怎么判断一段文本是否超过 5 行或者指定行数&#xff0c;并在超过时显示 "展开/收起" 按钮。那应该如何实现呢&#xff1f; 在 Vue 3 的项目下实现&#xff1a; <template><div class"text-container"><di…

计算机毕业设计 学院网站系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Java框架学习(Spring)(ioc)(01)

简介&#xff1a;以本片记录在尚硅谷学习ssm-spring-ioc时遇到的小知识 详情移步&#xff1a;想参考的朋友建议全部打开相互配合学习&#xff01; 视频&#xff1a; 014-spring-框架概念理解_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AP411s7D7?p14&vd_sou…

【楚怡杯】职业院校技能大赛 “云计算应用” 赛项样题九

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

GIS留学院校介绍-英国篇

看前须知 关于语言成绩要求&#xff1a; 通常英国院校的雅思成绩要求分为5个等级&#xff0c;标准分别如下&#xff1a; 1级&#xff1a;总分6.5分&#xff0c;每个部分最低6.0分 2级&#xff1a;总分7.0&#xff0c;每个部分至少6.5分 3级&#xff1a;总分7.0分&#xff…

2024年有什么开放式耳机推荐?盘点开放式蓝牙耳机排行榜前五名

​到了2024年&#xff0c;开放式耳机无疑成为了耳机市场的宠儿。它们的优势在于&#xff0c;不仅佩戴舒适&#xff0c;还能在保护听力的同时&#xff0c;让你保持对周围环境的警觉&#xff0c;这对于爱好户外探险的朋友来说&#xff0c;无疑是一个巨大的安全加分项。作为一名资…

(附源码)微信小程序的拼车设计-计算机毕设19413

微信小程序的拼车设计 摘 要 在微信小程序的拼车服务中&#xff0c;后端架构巧妙地运用了SSM&#xff08;Spring、SpringMVC、MyBatis&#xff09;框架&#xff0c;为用户带来了流畅、高效的体验。Spring框架作为整个系统的核心&#xff0c;不仅管理着业务逻辑&#xff0c;还通…

分布式光伏的发电监控

国拥有丰富的清洁可再生能源资源储量&#xff0c;积极开发利用可再生能源&#xff0c;为解决当前化石能源短缺与环境污染严重的燃眉之急提供了有效途径[1]。但是可再生能源的利用和开发&#xff0c;可再生能源技术的发展和推广以及可再生能源资源对环境保护的正向影响&#xff…

PCB生产,在钻咀和成品孔径之间,你会优先满足哪一项呢

高速先生成员--王辉东 曹梦总是说&#xff0c;人生如《忐忑》&#xff0c;虽然没有准确的歌词&#xff0c;却演绎的惊心动魄…… 她是工厂的工程评估员&#xff0c;对于PCB的热爱&#xff0c;就像拖拉机上山&#xff0c;轰轰烈烈&#xff0c;不知疲倦。 她一向秉承的原则是&…

Excel名字查重筛选,查找重复内容原来这么简单

大家好&#xff0c;这里是效率办公指南&#xff01; &#x1f50d; 在处理大量数据时&#xff0c;尤其是人员名单或客户信息时&#xff0c;确保没有重复的名字是非常重要的。在Excel中&#xff0c;有几种方法可以帮助我们快速查找和处理重复的名字。今天&#xff0c;我们将介绍…

[linux 驱动]块设备驱动详解与实战

目录 1 描述 2 结构体 2.1 block_device_operations 2.2 gendisk 2.3 block_device 2.4 request_queue 2.5 request 2.6 bio 3.7 blk_mq_tag_set 3.8 blk_mq_ops 3 相关函数 3.1 注册注销块设备 3.1.1 register_blkdev 3.1.2 unregister_blkdev 3.2 gendisk 结构…

算法思想之前缀和

前缀和&#xff1a;快速求出数组中某连续区间的和 一.一维前缀和(模板) 1.题目&#xff1a;【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 给定一个长度为n的数组a1,a2,....ana1​,a2​,....an​.&#xff0c;接下来有q次查询, 每次查询有两个参数l, r&#xff0c;对于每个…

打造你的专属主题-VitePress保姆级教程

本篇为vitepress系列教程&#xff0c;在开始前&#xff0c;若还不了解vitepress的小伙伴可以看一下以往文章&#xff1a; 不敲一行代码&#xff01;助你快速搭建属于自己的官网博客&#xff01;-VitePress保姆级教程 文章目录 VitePress主题配置准备自定义主题配置标题配置图标…

【软件文档资料】软件代码编写规范-交付文档支撑(Word原件)

&#xff08;一&#xff09;一开始就必须正确的使用规范 &#xff08;二&#xff09;简易性原则 &#xff08;三&#xff09;清晰性原则 &#xff08;四&#xff09;健壮性原则 &#xff08;五&#xff09;效率原则 软件资料清单列表部分文档清单&#xff1a;工作安排任务书&am…

visual studio 调试技巧

visual studio 调试技巧 概述 在使用visual studio 进行调试的时候&#xff0c;有几个调试方法很好用&#xff0c;这里做一些记录。 GTEST 单元测试 参考 VS2022创建C C GTEST工程 - Hello-FPGA - 博客园 (cnblogs.com) 内存查看 命令行测试动态库 附加到进程调试动态库 …

数造科技荣获“2024爱分析·数据智能优秀厂商”

近日&#xff0c;2024年第六届爱分析数据智能高峰论坛圆满举办。会议期间&#xff0c;“2024爱分析数据智能优秀厂商”榜单正式揭晓&#xff0c;数造科技凭借其卓越的技术创新能力与丰富的实践应用案例&#xff0c;脱颖而出&#xff0c;成功入选“数据智能优秀厂商”。 评选严苛…

青否数字人【电脑版】实景直播+视频直播正式发布!

9月份&#xff0c;我们团队去山东的多家直播基地、MCN 机构&#xff0c;和合作伙伴一起深入探讨了青否数字人在抖音直播的落地情况。 这一趟下来&#xff0c;收获满满&#xff0c;对青否数字人的下一步升级有了更清晰的规划。 今天&#xff0c;青否数字人电脑客户端迎来了大升级…