c++的学习之路:17、stack、queue与priority_queue

news2024/11/27 1:37:45

摘要

本文主要是介绍一下stack、queue、priority_queue的使用以及模拟实现,文章末附上代码以及思维导图。

目录

摘要

一、stack的介绍和使用

1、stack的介绍

2、stack的使用

3、stack的模拟实现

二、queue的介绍和使用

1、queue的介绍

2、queue的使用

3、queue的模拟实现

三、priority_queue的介绍和使用

1、priority_queue的介绍

2、priority_queue的使用

3、priority_queue的模拟实现

四、代码

1、stack

2、queue

3、priority_queue

五、思维导图


 

一、stack的介绍和使用

1、stack的介绍

和之前一样这里也是直接介绍一下文档,使用方式和之前的模板大差不差,如下方截图就是cplusplus的介绍,下面四点就是文档上面的翻译,其他的就不详细说了,数据结构里面有更加详细的介绍。

1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。

2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:

empty:判空操作

back:获取尾部元素操作

push_back:尾部插入元素操作

pop_back:尾部删除元素操作

4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。

44bcb71426bf4a689d374832a3cd9913.png

2、stack的使用

下面的一个表格就是常用的几个函数与接口说明,就不一一说明怎么使用了,和之前vector、list、string所演示的都差不多。

函数说明接口说明
stack()构造空的栈
empty()检测stack是否为空
size()返回stack中元素的个数
top()返回栈顶元素的引用
push()将元素val压入stack中
pop()将stack中尾部的元素弹出

3、stack的模拟实现

这里是直接利用vector作为一个缺省值,直接用模板去创建一栈,这样都可以直接复用vector的函数,这样实现起来就十分容易加上轻松了,如下方代码所示,因为栈不支持迭代器,不能遍历只能一次出一个结果如下方图片所示,其实这里是我康吃康吃写了一个类似c写的那种,然后看了一下源码,大佬不愧是大佬,好轻松。

3e9aa157bed34855b94dd30a65279803.png

namespace ly1
{
	template<class T, class Container = vector<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

	private:
		Container _con;
	};

	void Test_Stack()
	{
		stack<int> s1;
		s1.push(1);
		s1.push(2);
		s1.push(3);
		s1.push(4);
		while (!s1.empty())
		{
			cout << s1.top() << ' ';
			s1.pop();
		}
		cout << endl;
	}
}

 

 

二、queue的介绍和使用

1、queue的介绍

和之前一样这里也是直接介绍一下文档,使用方式和之前的模板大差不差,如下方截图就是cplusplus的介绍,下面四点就是文档上面的翻译,其他的就不详细说了,数据结构里面有更加详细的介绍。

1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。

2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

empty:检测队列是否为空

size:返回队列中有效元素的个数

front:返回队头元素的引用

back:返回队尾元素的引用

push_back:在队列尾部入队列

pop_front:在队列头部出队列

4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

865bf7703b4848bb98ef3e6209d45ce2.png

2、queue的使用

下面的一个表格就是常用的几个函数与接口说明,就不一一说明怎么使用了,和之前vector、list、string所演示的都差不多。

函数声明接口说明
queue()构造空的队列
empty()检测队列是否为空,是返回true,否则返回false
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素val入队列
pop()将队头元素出队列

3、queue的模拟实现

这里也是利用复用直接写的代码和测试如下。

20cbfa36b23d4182b3d06e44c00c6de2.png

namespace ly2
{
	template<class T, class Container = list<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

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

	private:
		Container _con;
	};

	void Test_Queue()
	{
		queue<int> q1;
		q1.push(1);
		q1.push(2);
		q1.push(3);
		q1.push(4);
		while (!q1.empty())
		{
			cout << q1.front() << " ";
			q1.pop();
		}
		cout << endl;
	}
}

三、priority_queue的介绍和使用

1、priority_queue的介绍

下面就是优先队列的文档介绍。

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。

2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。

3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。

4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

empty():检测容器是否为空size():返回容器中有效元素个数

front():返回容器中第一个元素的引用

push_back():在容器尾部插入元素

pop_back():删除容器尾部元素

5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。

6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

3d71be5c46fa4b24b82a51a625225966.png

2、priority_queue的使用

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

函数声明接口说明
priority_queue()/priority_queue(first,
last)
构造一个空的优先级队列
empty( )检测优先级队列是否为空,是返回true,否则返回
false
top( )返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素

3、priority_queue的模拟实现

这个原理有点像我之前写数据结构的堆,实现方法也差不多,这个优先队列可以进行排序,他默认是降序,代码实现与测试如下。

d2ad3092a0044fff9ccbc572b5f778f4.png

namespace ly3
{
	template<class T>
	struct less
	{
		bool operator()(const T& left, const T& right)
		{
			return left < right;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(const T& left, const T& right)
		{
			return left > right;
		}
	};

	template<class T, class Container = std::vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue() : c() {}
		template<class Iterator>
		priority_queue(Iterator first, Iterator last)
			: c(first, last)
		{
			int count = c.size();
			int root = ((count - 2) >> 1);
			for (; root >= 0; root--)
				AdjustDown(root);
		}

		void push(const T& data)
		{
			c.push_back(data);
			AdjustUP(c.size() - 1);
		}

		void pop()
		{
			if (empty())
				return;

			swap(c.front(), c.back());
			c.pop_back();
			AdjustDown(0);
		}

		size_t size()const
		{
			return c.size();
		}

		bool empty()const
		{
			return c.empty();
		}

		const T& top()const
		{
			return c.front();
		}
	private:
		void AdjustUP(int child)
		{
			int parent = ((child - 1) >> 1);
			while (child)
			{
				if (Compare()(c[parent], c[child]))
				{
					swap(c[child], c[parent]);
					child = parent;
					parent = ((child - 1) >> 1);
				}
				else
				{
					return;
				}
			}
		}

		void AdjustDown(int parent)
		{
			size_t child = parent * 2 + 1;
			while (child < c.size())
			{
				if (child + 1 < c.size() && Compare()(c[child], c[child + 1]))
					child += 1;
				if (Compare()(c[parent], c[child]))
				{
					swap(c[child], c[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					return;
			}
		}
	private:
		Container c;
	};

	void Test_Priority_Queue()
	{
		ly3::priority_queue<int> q1;
		q1.push(5);
		q1.push(1);
		q1.push(4);
		q1.push(2);
		q1.push(3);
		q1.push(6);
		while (!q1.empty())
		{
			cout << q1.top() << " ";
			q1.pop();
		}
		cout << endl;
	}
}

四、代码

1、stack

#pragma once

namespace ly1
{
	template<class T, class Container = vector<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

	private:
		Container _con;
	};

	void Test_Stack()
	{
		stack<int> s1;
		s1.push(1);
		s1.push(2);
		s1.push(3);
		s1.push(4);
		while (!s1.empty())
		{
			cout << s1.top() << ' ';
			s1.pop();
		}
		cout << endl;
	}
}

2、queue

#pragma once

namespace ly2
{
	template<class T, class Container = list<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

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

	private:
		Container _con;
	};

	void Test_Queue()
	{
		queue<int> q1;
		q1.push(1);
		q1.push(2);
		q1.push(3);
		q1.push(4);
		while (!q1.empty())
		{
			cout << q1.front() << " ";
			q1.pop();
		}
		cout << endl;
	}
}

3、priority_queue

#pragma once

namespace ly3
{
	template<class T>
	struct less
	{
		bool operator()(const T& left, const T& right)
		{
			return left < right;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(const T& left, const T& right)
		{
			return left > right;
		}
	};

	template<class T, class Container = std::vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue() : c() {}
		template<class Iterator>
		priority_queue(Iterator first, Iterator last)
			: c(first, last)
		{
			int count = c.size();
			int root = ((count - 2) >> 1);
			for (; root >= 0; root--)
				AdjustDown(root);
		}

		void push(const T& data)
		{
			c.push_back(data);
			AdjustUP(c.size() - 1);
		}

		void pop()
		{
			if (empty())
				return;

			swap(c.front(), c.back());
			c.pop_back();
			AdjustDown(0);
		}

		size_t size()const
		{
			return c.size();
		}

		bool empty()const
		{
			return c.empty();
		}

		const T& top()const
		{
			return c.front();
		}
	private:
		void AdjustUP(int child)
		{
			int parent = ((child - 1) >> 1);
			while (child)
			{
				if (Compare()(c[parent], c[child]))
				{
					swap(c[child], c[parent]);
					child = parent;
					parent = ((child - 1) >> 1);
				}
				else
				{
					return;
				}
			}
		}

		void AdjustDown(int parent)
		{
			size_t child = parent * 2 + 1;
			while (child < c.size())
			{
				if (child + 1 < c.size() && Compare()(c[child], c[child + 1]))
					child += 1;
				if (Compare()(c[parent], c[child]))
				{
					swap(c[child], c[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					return;
			}
		}
	private:
		Container c;
	};

	void Test_Priority_Queue()
	{
		ly3::priority_queue<int> q1;
		q1.push(5);
		q1.push(1);
		q1.push(4);
		q1.push(2);
		q1.push(3);
		q1.push(6);
		while (!q1.empty())
		{
			cout << q1.top() << " ";
			q1.pop();
		}
		cout << endl;
	}
}

五、思维导图

2ce6242b15454aa6b6f0dcfe3a619a29.png

 

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

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

相关文章

Vue-B站学习笔记

1. 路由配置 B站视频之Vue route文件下的index.js app.vue

Nginx服务 重写功能与反向代理

六、重写功能 rewrite Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求&#xff0c;此功能依靠 PCRE(perl compatible regular expression)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite是nginx服务器的重要功能之一&#xff0c;用于实现URL的…

土耳其航空2023年共运送旅客8340万人次,境内境外航线运力稳步增长

2023年,尽管面对持续紧张的国际局势和摇摆不定的宏观经济,土耳其航空仍实现了里程碑式的业绩表现,共计运输旅客8340万人次。土耳其境内航线运力比2022年增长了23.5%,运送旅客突破3000万人次;国际航线运力增长16%,运送旅客达5300万人次,并实现了14%的同比增长。其中,来自欧洲国家…

【Leetcode】2009. 使数组连续的最少操作数

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个整数数组 n u m s nums nums 。每一次操作中&#xff0c;你可以将 n u m s nums nums 中 任意 一个元素替换成 任意 整数。 如果 n u m s nums nums 满足以下条件&…

开创加密资产新纪元:深度解析ERC-314协议

随着加密资产市场的不断发展和区块链技术的日益成熟&#xff0c;新的协议和标准不断涌现&#xff0c;其中包括了ERC-314协议。本文将深入分析ERC-314协议的特点、功能以及对加密资产市场可能产生的影响。 1. ERC-314协议简介 ERC-314协议是一项建立在以太坊区块链上的新提案&a…

将精益IT和ITSM相结合,为客户和员工创造价值

在被要求使用精益 IT 之前&#xff0c;我已经从事IT服务管理 (ITSM)、运营、高级 IT 领导和顾问工作 30 多年了。那么什么是精益IT呢&#xff1f; 我的首席信息官派我去巴黎参加由 Steve Bell 和 Mike Orzen&#xff08;精益 IT 的作者&#xff09;主持的第一届精益 IT 会议。我…

使用ADO.NET访问数据库

目录 访问数据库的步骤 &#xff11;、建立数据库 &#xff12;、设置链接参数 &#xff08;1&#xff09;web网页和数据库连接的方法一 &#xff08;2&#xff09;web网页和数据库连接的方法二 &#xff13;、建立链接对象 &#xff14;、显示数据库 &#xff15;、数…

el-table 表格分页序号问题

el-table-column 本身提供typeindex 但是每次切换分页 序号都是1-9 想要获取当前页数的条数序号 获取不到 <el-table-column label"序号" width"60" align"center"><template #default"scope"><div>{{ (queryPara…

数据库之DQL操作(数据查询语言)

DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。查询关键字: SELECT。 本节介绍以下表为例&#xff1a; create table emp(id int comment 编号&#xff0c;workno varchar(10) comment 工号&#xff0c;nam…

解决npm install安装node-sass包容易失败的问题

具体问题如下&#xff1a; npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: XXX3.4.0 npm ERR! Found: webpack5.31.2 npm ERR! node_modules/webpack npm ERR! peer webpack”^4.0.0 || ^5.0.0″ from html-…

学生台灯护眼灯哪个牌子好?护眼台灯推荐儿童必备

当前&#xff0c;青少年及儿童的近视率居高不下&#xff0c;实际数据甚至超出了半数的比例。这意味着超过一半的孩子们可能面临着某种程度的视力问题&#xff0c;这一现象无疑让每位家长的心都紧绷起来&#xff0c;对孩子的视力健康格外关注。尤其是孩子学习时使用的那一盏台灯…

心灵鸡汤之励志正能量文案,积极向上热爱生活短句

1、在一切变好之前&#xff0c;我们总要经历一些不开心的日子&#xff0c;这段日子也许很长&#xff0c;也许只是一觉醒来。有时候&#xff0c;选择快乐&#xff0c;更需要勇气。 2、靠自己&#xff0c;才能无惧艰难&#xff0c;靠他人&#xff0c;永远害怕风霜&#xff0c;别…

【第二十七篇】几款配合Burpsuite使用的Google插件(Wappalyzer、FindSomething、FOFAproView等)

文章目录 WappalyzerFindSomethingFOFA Pro ViewsuperSearchPluswayback machinesource detecotorX-Forwarded-For Header以下插件均在Google应用商店中下载 Wappalyzer Wappalyzer是一个用于识别网站所使用的技术和工具的浏览器扩展程序。它能够检测出网站所使用的内容管理系…

操作系统(第三周 第二堂)

目录 ⚽回顾 &#x1f3d0;进程管理&#xff08;process&#xff09; 进程理解&#xff08;总结&#xff09; 进程 程序到进程 内存中的进程 进程状态 状态类型 状态转移 进程控制块 &#x1f3c0;总结 回顾 前一篇文章的重点在于操作系统的结构&#xff0c;从简单…

【数据结构】考研真题攻克与重点知识点剖析 - 第 8 篇:排序

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…

Java每日一题

我的思路: 1.排序 2.固定一个数&#xff0c;然后将问题转换为俩个数之和为固定数的相反数 3.在固定数&#xff0c;后面利用"双指针算法"快速找到两个的和等于-a即可 4.处理这个题的细节问题 1.去重 找到一个结果之后&#xff0c;将left和right指针要跳过前面的重复元…

MLOps 体系结构模型

人工智能继续改变企业&#xff0c;但这导致企业在数字化转型和组织变革方面面临新的挑战。根据 2023 年福布斯报告&#xff0c;这些挑战可以总结如下&#xff1a; 分析技术堆栈围绕分析/批处理工作负载构建的公司需要开始适应实时数据处理&#xff08;福布斯&#xff09;。这种…

【保姆级讲解PyCharm安装教程】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

js获取上周本周下周的日期(附Demo)

目录 前言1. 基本知识2. Demo3. 彩蛋 前言 现在的时间点是&#xff1a;2024-04-08&#xff0c;对应的日期如下&#xff08;上周、这周、下周&#xff09; 1. 基本知识 讲述Demo之前&#xff0c;先补充一些基础知识 JavaScript 中的 Date 对象是用于处理日期和时间的对象。它…

博客系统实现

一.准备工作 1.创建项目&#xff0c;把前端写好的博客静态页面拷贝到webapp目录中 2.引入依赖&#xff0c;这里主要用到servlet&#xff0c;mysql5.1.47&#xff0c;jacson2.15.0 3.找到右上角的edit configurations->smartTomcat->进行配置 4.数据库设计&#xff1a…