[STL --stack_queue详解]stack、queue,deque,priority_queue,容器适配器

news2025/1/8 12:48:43

stack

stack介绍

1、stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
2、stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

 stack的使用

常用操作:

push尾部插入
pop尾部删除元素
top取栈顶元素
empty判空操作

stack的模拟实现

从stack的接口中,我们发现stack是一种特殊的vector,因此可以用vector完全模拟实现stack;

namespace bit {
	/*template<class T>
	class stack {
	private:
		T* _a;
		int _top;
		int _capacity;
	};*/

	//可维护性
	//设计模式
	//适配器  -- 转换
	template<class T,class Container =vector<T>>
	class stack {
	public:
		void push(const T&x) {
			_con.push_back(x);
		}
		void pop() {
			_con.pop_back();
		}
		bool empty() {
			return _con.empty();
		}
		const T& top() {
			return _con.back();
		}
		size_t size() {
			return _con.size();
		}
	private:
		Container _con;
	};
}

当然用list,deque也可以模拟实现栈;

bit::stack<int, list<int>>s;
bit::stack<int, vector<int>>s;
bit::stack<int, deque<int>>s;

queue

queue介绍

1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

queue的使用

push队尾插入
pop对头删除
front返回对头元素的引用
back返回队尾元素的引用
empty队列是否为空
size队列元素有效个数

priority_queue 

这里的priority_queue是按照优先级出的,底层实现是堆结构;

这里补充一下要用到的堆的知识点:

堆向上调整:

		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;
				}
			}
		}

堆向下调整:


		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[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else {
					break;
				}
			}
		}

在模拟实现优先队列前,我们先了解一下仿函数:

 仿函数是什么?

看一段代码:

class Func {
public:
    //operator()就是函数名
    void operator()() {
        cout << "func调用" << endl;
    };
};

调用:

    Func f;
    f();
    f.operator()();

 仿函数(Functor) 是一种行为类似函数的对象,它可以被用作函数并接受参数。在C++中,仿函数通常是重载了函数调用运算符operator()的类对象。通过重载operator(),仿函数可以像函数一样被调用,并且可以保存状态信息。

这样利用仿函数,我们就可以把向上调整和向下调整修改调用仿函数:

这样我们需要大堆或者小堆的话就不要每次都修改<,>了,

    template<class T,class Container = vector<T>,class Compare=myless<T>>

 只需要:

默认是大堆;

小堆: 

   bit::priority_queue<int, vector<int>, bit::mygreater<int>>q1(v.begin(), v.end());

下面让我们来模拟实现优先队列:

namespace bit {

	//仿函数
	template<class T>
	class myless {
	public:
		bool operator()(const T& x, const T& y) {
			return x < y;
		}
	};
	//仿函数
	template<class T>
	class mygreater {
	public:
		bool operator()(const T& x, const T& y) {
			return x > y;
		}
	};

	template<class T,class Container = vector<T>,class Compare=myless<T>>
	class priority_queue {
	public:

		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);
			}
		}


		void AdjustUp(int child) {
			Compare comfunc;
			int parent = (child - 1)/2;
			while (child>0) {

				if (comfunc(_con[parent], _con[child])) {
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else {
					break;
				}
			}
		}
		void AdjustDown(int parent) {
			Compare comfunc;
			int child = parent * 2 + 1;
			
			while (child < _con.size()) {
				if (child+1<_con.size() && comfunc(_con[child] , _con[child + 1])) {
					child++;
				}
				if (comfunc(_con[parent] , _con[child])) {
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else {
					break;
				}
			}
		}

		void push(const T& x) {
			_con.push_back(x);
			AdjustUp(_con.size()-1);
		}
		void pop() {
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);
		}
		const T& top() {
			return _con[0];
		}
		bool empty() {
			return _con.empty();
		}
		size_t size() {
			return _con.size();
		}
	private:
		Container _con;//底层核心
	};
}

queue的模拟实现

由于queue是一个双端操作,这里最后不要使用vector在模拟实现,如果用的话反而会比较麻烦。

可以选择list和deque来模拟实现;

    bit::queue<int, list<int>>s;
    bit::stack<int, deque<int>>s;

namespace bit {

	template<class T,class Container = list<T>>
	class queue {
	public:
		void push(const T& x) {
			_con.push_back(x);
		}
		void pop() {
			_con.pop_front();
		}
		bool empty() {
			return _con.empty();
		}
		size_t size() {
			return _con.size();
		}
		const T&top() {
			return _con.front();
		}
	private:
		Container _con;
	};
}

deque简单介绍

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

简单的说,deque在功能上就是vector和list的结合。

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组。
 

什么是适配器?

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

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

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

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

相关文章

原理图库和PCB库的命名规范及创建封装、使用封装管理器

原理图库 命名规范 原理图中元件值标注规则 注&#xff1a;元件值&#xff08;Component Value&#xff09;就是元件最主要的特征对应的值。 Component value. Most analog components have a value that must be specified by this field (e.g., 2.7 kΩ). Additional disti…

c++数据结构之队列

目录 一、队列的含义 1.队列的使用 2.队列的结构 二、顺序队列的实现 1.队列的定义 2.队列的初始化 3.清空对列 4.队列是否为空 5.获取队列的长度 6.获取头元素的值 7.入队列 8.出队列 9.遍历队列中的值 10.总代码 11.打印结果 三、链表队列的实现 1.队列的…

【Hot100】LeetCode—347. 前 K 个高频元素

目录 1- 思路自定义Node结点 哈希表实现 2- 实现⭐347. 前 K 个高频元素——题解思路 3- ACM实现 原题连接&#xff1a;347. 前 K 个高频元素 1- 思路 自定义Node结点 哈希表实现 ① 自定义 Node 结点&#xff1a; 自定义 Node 结点中有 value 和 cnt 字段&#xff0c;其中…

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

html css网页制作

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; HTML 和 CSS 是制作网页的基础。HTML 用于定义网页的结构和内容&#xff0c;CSS 用于设计网页的样式和布局。以下是一个详细的网页制作成品教程&#xff0c;包括 HTML 和 CSS 的基础知识&#xff0c;及如何…

MySQL基础(7)- 多表查询

目录 一、笛卡尔积的错误与正确的多表查询 1.出现笛卡尔积错误 2.正确的多表查询&#xff1a;需要有连接条件 3.查询多个表中都存在的字段 4.SELECT和WHERE中使用表的别名 二、等值连接vs非等值连接、自连接vs非自连接 1.等值连接 vs 非等值连接 2.自连接 vs 非自连…

安卓逆向(之)真机root(红米手机)

概览&#xff1a; 1, 手机解锁 2, 下载官方系统包&#xff0c;推荐线刷包,取出镜像文件 3, magisk工具修补 官方系统包 4, adb&#xff1a;命令对手机刷 root 5, 完成 6, 小米手机解锁 点击 小米手机解锁OEM官方教程 记得数据线连接手机电脑 工具下载 点击 下载adb(电脑操作…

进程间通信-进程池

目录 理解​ 完整代码 完善代码 回收子进程&#xff1a;​ 不回收子进程&#xff1a; 子进程使用重定向优化 理解 #include <iostream> #include <unistd.h> #include <string> #include <vector> #include <sys/types.h>void work(int rfd) {…

Windows下使用cmake编译OpenCV

Windows下使用cmake编译OpenCV cmake下载OpenCV下载编译OpenCV cmake下载 下载地址&#xff1a;https://cmake.org/download/ 下载完成&#xff0c;点击选择路径安装即可 OpenCV下载 下载地址&#xff1a;https://github.com/opencv/opencv/releases/tag/4.8.1因为我们是编译…

2024软件测试需要具备的技能(软技能硬技能)

软件测试的必备技能 在往期的文章分享了很多的面试题&#xff0c;索性做一个转型。从零基础开始讲解&#xff0c;结合面试题来和大家一起学习交流软件测试的艺术。 第一个是专业技能&#xff0c;也叫硬技能。 第二个叫做软技能。 我们在上一篇文章中讲到了软件测试流程的5个…

ChatGPT在论文写作领域的应用:初稿设计

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 学术论文写作中&#xff0c;内容清晰、结构合理的初稿至关重要。通过 ChatGPT&#xff0c;写作者可以快速生成内容框架、明确研究问题&#xff0c;并优化表达方式。不仅提高了写作效率&…

笔记整理—内核!启动!—kernel部分(1)驱动与内核的关系

首先&#xff0c;恭喜完成了uboot部分的内容整理&#xff0c;其次补充一点&#xff0c;uboot第一部分和第二部分的工作不是一定的&#xff0c;在不同的版本中&#xff0c;可能这个初始化早一点&#xff0c;那个的又放在了第二部分&#xff0c;版本不同&#xff0c;造成的工作顺…

滑动窗口——632. 最小区间

最近在抽时间写LC上的一个专栏——2024春招冲刺百题计划。挑着做&#xff0c;做了几道和滑动窗口相关的题目&#xff0c;632. 最小区间&#xff0c;LC上标记为困难&#xff0c;第一次写完全没有思考&#xff0c;参考了别人写的答案茅塞顿开&#xff0c;特此记录以鞭策自己学习。…

Android perfetto 简介

Android perfetto 简介 使用 perfetto 工具&#xff0c;您可以通过 Android 调试桥 (adb) 在 Android 设备上收集性能信息。使用 adb shell perfetto ... 命令调用 perfetto 工具。 perfetto 从您的设备上收集性能跟踪数据时会使用多种来源&#xff0c;例如&#xff1a; 使用…

5、const修饰类型和变量

const修饰类型和变量 一、const常量一些注意点1、声明时必须同时初始化2、不可更改3、与宏常量的区别 二、const修饰指针1、常量指针constant pointer2、常指向指针pointer-to-constant pointer 一、const常量一些注意点 1、声明时必须同时初始化 #include <iostream> …

框架template初识

框架初识 框架就是一个别人帮我们搭好的舞台&#xff0c;造好了很多现成的工具供我们使用&#xff0c;让开发过程更快速、简洁。 Gin框架介绍 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 Gin是一个用Go语言编写的web框架。它是一个类似于martini 但拥有更好性能的API…

企业网银登录提示请确认您已插入工商银行U盾证书的解决方法

昨天受人之托帮小企业财务解决上网银的问题 因为不是专业做这个的&#xff0c;所以只能安装“常识”行事&#xff0c;但结果实在是令人意想不到。 排错的步骤&#xff1a; 同一台电脑上尝试不同浏览器&#xff0c;发现360浏览器的接受度相当普遍&#xff1b;给U盾换不同的连接…

抖音引流脚本工具,实现自动化引流,解放大家双手

抖音引流脚本工具,实现自动化引流,解放大家双手 #获客引流 推荐阅读&#xff1a; 百收网SEO引流脚本软件不断更新&#xff08;推广全集教程&#xff09;https://www.bsw80.com/post/460.html 我们这篇文章的话&#xff0c;来去给大家说一下这个抖音这个同城评论&#xff0c;…

探索 RAD:5 个最佳实践案例解析

天下武功&#xff0c;唯快不破&#xff01;应用开发&#xff0c;唯速称王&#xff01; 在当今快速发展的科技环境中&#xff0c;企业面临的挑战不断升级。传统的应用开发方法往往因其复杂的流程和较长的开发周期而无法满足快速变化的市场需求。在这种背景下&#xff0c;快速应…

【阿里云】个人认证与公司认证

个人认证和企业认证的区别 更新时间&#xff1a;2024-05-20 09:32:52 本文档主要介绍个人认证账号和企业认证账号的区别。 账号实名认证分为个人实名认证和企业实名认证。 个人账号认证&#xff0c;请选择认证类型为 个人&#xff0c;支持个人支付宝授权认证和个人扫脸认证。…