【C++】stack、queue模拟实现

news2025/1/8 5:55:14

💗个人主页💗
⭐个人专栏——C++学习⭐
💫点击关注🤩一起学习C语言💯💫

目录

导读

1. stack和queue的底层

1.1 stack

1.2 queue

2. 什么是适配器

3. 常见适配器

4. stack具体实现

4.1 成员变量

4.2 push函数

4.3 pop函数

4.4 size函数

4.5 empty函数

4.6 top函数 

5. stack实现完整代码 

5.1 stack.h

5.2 test.cpp

6. queue具体实现

6.1 成员变量

6.2 push函数

6.3 pop函数

6.4 size函数

6.5 empty函数

6.6 front和back函数

7. queue实现完整代码

7.1 queue.h

7.2 test.cpp


导读

我们上次了解了stack和queue的一些基本使用,今天我们就来试着实现一下。

1. stack和queue的底层

1.1 stack

C++中的stack通常是由deque(双端队列)或vector(动态数组)实现的。这是因为deque和vector都提供了方便的尾部插入和删除操作,符合stack的后进先出(LIFO)原则。

  • 如果使用deque实现stack,那么每次将元素推入栈顶时,将元素插入到deque的尾部;而每次从栈顶弹出元素时,从deque的尾部删除元素。这样可以快速实现栈的操作,并保持栈的后进先出的特性。
  • 如果使用vector实现stack,那么每次将元素推入栈顶时,将元素插入到vector的尾部;而每次从栈顶弹出元素时,从vector的尾部删除元素。类似地,这样也可以实现栈的操作,但由于vector是动态数组,所以在元素数量超过vector的当前容量时,可能需要重新分配内存并复制元素,这可能导致性能损失。

C++的标准库中还提供了适配器(adapter)stack,它基于deque或vector实现,隐藏了底层容器的实现细节,并提供了方便的栈操作接口。这样可以在不直接操作底层容器的情况下使用stack,使代码更加简洁和易读。

需要注意的是,由于stack只提供了后进先出的操作,没有提供随机访问元素的能力,因此不支持迭代器遍历。如果需要遍历栈中的元素,可以通过反复弹出栈顶元素并处理,直到栈为空。

1.2 queue

queue是一个基于适配器模式实现的容器适配器。它是一个先进先出(FIFO)的数据结构,内部使用一个底层容器来存储元素。

默认情况下,queue使用deque作为其底层容器。deque是一种双向队列,支持快速在头部和尾部进行插入和删除操作,因此适合作为queue的底层容器。

通过适配器的方式,queue将底层容器的接口封装起来,提供了一组符合先进先出原则的操作。这使得使用queue变得更加方便、简洁,并且可以灵活地选择底层容器类型,以满足特定的需求。如果需要自定义底层容器,可以通过模板参数来指定特定的容器类型。

2. 什么是适配器

适配器(Adapter)是一种设计模式,用于将一个类的接口转换为客户端所期望的另一个接口。适配器模式允许原本不兼容的类能够一起工作。

适配器通常有两种类型:

  1. 类适配器:使用多重继承的方式,将被适配类的接口转换为目标接口。适配器继承被适配类,并实现目标接口。
  2. 对象适配器:通过组合的方式,将适配器对象与被适配对象关联起来,将被适配类的接口转换为目标接口。适配器实现目标接口,并在内部持有被适配对象的实例。

适配器模式常用于以下情况:

  • 当需要使用一个已经存在的类,但其接口与现有代码不兼容时,可以使用适配器模式将其接口转换为目标接口。
  • 当需要复用一些现有类,但是这些类不具备与所需接口匹配的方法时,可以使用适配器模式添加额外的逻辑,实现所需接口。

总结来说,适配器模式可以让原本不兼容的类能够一起工作,实现接口转换和兼容性。

3. 常见适配器

以下是C++中的一些常见适配器:

  1. stack:适配器stack用于将deque或vector等底层容器实现为后进先出(LIFO)的栈。

  2. queue:适配器queue用于将deque或list等底层容器实现为先进先出(FIFO)的队列。

  3. priority_queue:适配器priority_queue用于将vector或deque等底层容器实现为优先级队列,其中元素按照一定的优先级顺序排列。

  4. stack和queue的适配器:C++标准库还提供了两个适配器,即stack和queue,它们可以使用deque、list或vector等底层容器作为实现。这样可以根据需求选择不同的底层容器,以满足不同的性能要求。

这些适配器通过封装底层容器的实现,提供了一种统一的接口,使得程序员可以方便地使用这些数据结构和算法,而不需要关心底层容器的具体实现细节。此外,适配器还提供了简化和抽象的功能,使得代码更加易读和可维护。

4. stack具体实现

4.1 成员变量

    //第二个模板参数给一个缺省值(只能从右往左给)
	template<class T, class Container = vector<T>>
	class stack
	{
	private:
		Container _con;
	};

Container表示用于存储栈元素的容器类型,默认情况下使用vector<T>作为容器类型。可以通过实例化stack类时指定具体的容器类型。

通过使用模板类stack,可以实例化不同类型元素的栈,并且可以灵活选择底层容器类型。例如,可以创建一个存储整数类型的栈:stack<int>,默认使用vector<int>作为容器。也可以创建一个存储字符串类型的栈:stack<string, list<string>>,使用list<string>作为容器。

4.2 push函数

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

具体来说,这个函数使用了_con容器的push_back()成员函数,将元素x插入到容器的尾部。

每次调用push()函数,新元素都会被添加到底层容器的尾部,实现了栈的特性:后进先出(LIFO)。

4.3 pop函数

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

pop函数使用了底层容器_conpop_back()成员函数,它会从底层容器的末尾弹出一个元素。

4.4 size函数

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

 这个函数使用了_con容器的size()成员函数,它会返回底层容器的元素个数。

4.5 empty函数

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

 

这是stack类中的empty函数的实现。它执行的操作是判断底层容器是否为空。

具体来说,这个函数使用了_con容器的empty()成员函数,它会检查底层容器是否为空。如果底层容器为空,返回true,否则返回false

4.6 top函数 

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

top函数使用了底层容器_conback()成员函数,它返回底层容器中的最后一个元素,即栈中的顶部元素。

5. stack实现完整代码 

5.1 stack.h

#pragma once
#include <iostream>
using namespace std;
#include <vector>

namespace Mystack
{
	//第二个模板参数给一个缺省值(只能从右往左给)
	template<class T, class Container = vector<T>>
	class stack
	{
	public:

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

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

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

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

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

}

5.2 test.cpp

#include "stack.h"

void test_stack()
{
	Mystack::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;
}

int main()
{
	test_stack();

	return 0;
}

6. queue具体实现

6.1 成员变量

	template<class T, class Container = deque<T>>
	class queue
	{
	private:
		Container _con;
	};

这是一个queue类的模板定义。它使用一个模板参数T来表示元素的类型,并使用一个模板参数Container来表示底层容器的类型,默认为deque<T>。

在这个queue类中,私有成员变量_con表示底层容器,用于存储元素。它的类型是通过模板参数Container来确定的,默认情况下是deque<T>类型。

这个模板类定义了一个基本的队列数据结构,使得用户可以方便地在底层容器上进行队列操作,例如入队、出队、获取队头元素等。具体的队列操作实现可以通过对底层容器的操作来完成。

6.2 push函数

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

这个函数使用了_con容器的push_back()成员函数,将元素x插入到容器的尾部。在deque容器中,push_back()函数的时间复杂度为常数时间,可以快速地将元素添加到容器的尾部。

6.3 pop函数

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

 这个函数使用了_con容器的pop_front()成员函数,它会删除底层容器的第一个元素。在deque容器中,pop_front()函数的时间复杂度为常数时间,因此可以快速地删除第一个元素。

6.4 size函数

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

这是queue类中的size函数的实现。它执行的操作是返回底层容器的元素个数。

具体来说,这个函数使用了_con容器的size()成员函数,它会返回底层容器的元素个数。在deque容器中,size()函数的时间复杂度为常数时间,因此可以快速地获取元素个数。

6.5 empty函数

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

这是queue类中的empty函数的实现。它执行的操作是判断底层容器是否为空。

具体来说,这个函数使用了_con容器的empty()成员函数,它会检查底层容器是否为空。如果底层容器为空,返回true,否则返回false

6.6 front和back函数

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

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

 这是queue类中的frontback函数的实现。它们分别返回队列的第一个元素和最后一个元素的引用。

具体来说,front函数使用了底层容器_confront()成员函数,它会返回底层容器的第一个元素的引用。back函数则使用了_conback()成员函数,它返回底层容器的最后一个元素的引用。

这样,可以通过调用front()back()函数来访问队列的第一个元素和最后一个元素,而不需要直接操作底层容器。

7. queue实现完整代码

7.1 queue.h

#pragma once
#include <iostream>
using namespace std;
#include<deque>

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

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

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

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

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

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

7.2 test.cpp

#include "queue.h"

void test_queue1()
{
	Myqueue::queue<int> q;
	q.push(1);
	q.push(2);

	cout << q.front() << " ";
	q.pop();

	q.push(3);
	q.push(4);

	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}
	cout << endl;
}
int main()
{
	test_queue1();

	return 0;
}

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

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

相关文章

Solr7.4.0报错org.apache.solr.common.SolrException

文章目录 org.apache.solr.common.SolrException: Exception writing document id MATERIAL-99598435990497269125316 to the index; possible analysis error: cannot change DocValues type from NUMERIC to SORTED_NUMERIC for field "opt_time"Exception writing…

震坤行坤合供应链荣获“2024 LOG低碳供应链物流-最具影响力品牌商”

震坤行坤合供应链荣获“2024 LOG低碳供应链物流-最具影响力品牌商” 近日&#xff0c;罗戈网在青岛举办了2024第三届低碳供应链&物流创新发展高峰论坛&#xff0c;此次峰会聚焦“物流碳中和&#xff0c;可持续供应链”这一核心议题&#xff0c;汇聚国内外双碳践行企业、低碳…

MyBatis 动态 SQL 的详细内容讲解

1. MyBatis 动态 SQL 的详细内容讲解 文章目录 1. MyBatis 动态 SQL 的详细内容讲解2. 准备工作3. if 标签4. where 标签5. trim 标签6. set 标签7. choose when otherwise 标签8. foreach 标签8.1 批量删除8.2 批量添加 9. SQL 标签与 include 标签10. 总结&#xff1a;11. 最…

文案提取小帮手轻松将视频为转文字!而且不限时长

作为一个自媒体的资深用户总在一个一个的敲字真的太慢了&#xff0c;而且很多创作者都知道追热点是和时间赛跑。如果你嫌弃自己手抄效率太低&#xff0c;看视频又嫌时间太长。 今天叫教你一个可以将视频转文字的工具&#xff0c; 这个工具就叫文案提取小帮手&#xff0c;而且…

企业如何平滑替换微软AD,构筑信创身份基座?

据统计&#xff0c;全球有超过91%的具规模企业将Microsoft Active Directory&#xff08;微软AD&#xff09;作为数字化身份的基础底座&#xff0c;其不仅为Windows系统、Exchange等应用提供统一认证与管理&#xff0c;还兼容了云桌面、EPR、OA等应用&#xff0c;应用范围广泛。…

python -- 异步、asyncio

文章目录 协程实现协成的方法greenlet实现协程yield 关键字asyncio async & await&#xff08;**重点**&#xff09; 协程的意义异步编程事件循环快速上手awaitTask对象asyncio.Future对象concurrent.futures.Future 对象 协程 协成不是操作系统提供的&#xff0c;是程序员…

超市陈列艺术:不仅仅是货品摆放,更是营销策略的体现

品类管理在门店落地的最直观表现就是单品的空间陈列管理&#xff0c;通过陈列细节的差异体现出门店的商品定位与策略。此文分析入木三分&#xff0c;值得学习。 在商品陈列的空间管理领域&#xff0c;不仅要考虑整体的空间陈列&#xff0c;也要对每个商品的空间陈列位置&#…

工作神器大合集

在当代的工作环境里&#xff0c;软件工具扮演了不可或缺的角色&#xff0c;它们的设计初衷就是为了提高工作的效率与质量。下面将推荐五款值得使用的工作效率软件&#xff1a; 1、亿可达 作为一款自动化工具&#xff0c;亿可达被誉为国内版的免费Zaiper。它允许用户无需编程知…

DIYGW可视化开发工具:微信小程序与多端应用开发的利器

一、引言 随着移动互联网的飞速发展&#xff0c;微信小程序以其轻便、易用和跨平台的特点受到了广泛关注。然而&#xff0c;微信小程序的开发相较于传统的H5网页开发&#xff0c;在UI搭建和交互设计上存在一定的挑战。为了应对这些挑战&#xff0c;开发者们一直在寻找更加高效…

Ubuntu20.04.6操作系统安装教程

一、VMware Workstation16安装 选择安装VMware Workstation&#xff0c;登录其官网下载安装包&#xff0c;链接如下&#xff1a; 下载 VMware Workstation Pro 下载后运行安装向导&#xff0c;一直Next即可。 二、Ubuntu镜像下载 ubuntu20.04 选择需要下载的镜像类型下载即…

CobaltStrike权限传递MSF

一、测试环境 操作系统&#xff1a; 1.VMware17 2.kali 6.1.0-kali5-amd64 3.Win10x64 软件&#xff1a; 1.cs4.0 2.metasploit v6.3.4-dev 二、测试思路 1.cs是一款渗透测试工具&#xff0c;但没有漏洞利用的模块&#xff0c;我们可以在拿到目标主机的权限后&#xff0c;将…

代码解读 | Hybrid Transformers for Music Source Separation[05]

一、背景 0、Hybrid Transformer 论文解读 1、代码复现|Demucs Music Source Separation_demucs架构原理-CSDN博客 2、Hybrid Transformer 各个模块对应的代码具体在工程的哪个地方 3、Hybrid Transformer 各个模块的底层到底是个啥&#xff08;初步感受&#xff09;&#xff1…

工厂环境中ESD防静电系统对静电灾害的预防与控制

静电在工厂环境中可能造成严重的危害&#xff0c;包括火灾、爆炸和设备损坏等。因此&#xff0c;对于工厂环境中的静电灾害&#xff0c;采取预防和控制措施是非常必要的。ESD防静电系统是一种用来预防和控制静电灾害的重要解决方案&#xff0c;它可以有效地降低静电危害发生的可…

MCGS仿真教学1:单个变量与博途进行通讯

目录 一、博途配置1.1、博途通讯常用配置1.2、博途测试程序 二、MCGS配置2.1、工程配置2.2、设备组态2.3、添加单个变量2.4、添加画面2.4.1、按钮2.4.2、指示灯 三、下载测试 一、博途配置 1.1、博途通讯常用配置 1.2、博途测试程序 二、MCGS配置 2.1、工程配置 选择自己所购…

ubuntu18.04离线源制作

给客户部署有时需要纯内网环境&#xff0c;那这样就连不了网络。 一些包就下载不下来&#xff0c;而大家都知道用deb离线安装是非常麻烦的&#xff0c;各种依赖让你装不出来。 这里教大家打包源。 我准备2台机器&#xff0c;42和41 42可以联网&#xff0c;41不能联网。我想在…

python的a[:2]、a[:] 和a [::] 的区别

一、a[:2] 数据准备 import numpy as np X np.array([[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[16,17],[18,19]]) print(X)形成矩阵 print (“X[: 2]:”, X[: 2]) ### :表示索引 0至1行&#xff1b; 二、a[:]和a [::] 在 Python 中&#xff0c;[:] 和 [::…

修改版的VectorDBBench更好用

原版本VectorDBBench的几个问题 在这里就不介绍VectorDBBench是干什么的了&#xff0c;上官网即可。 1.并发数设置的太少 2.测试时长30秒太长 3.连接milvus无用户和密码框&#xff0c;这个是最大的问题 4.修改了一下其它参数 由于很多网友发私信问一些milvus的相关技术问…

钓鱼小助手 —— 借助文心智能体平台打造钓鱼佬神器

前言 &#x1f680;前方高能 &#x1f680;钓鱼小助手上线了 有没有喜欢钓鱼的程序猿呀&#xff0c;福利来了&#xff0c;特意整了一个钓鱼的小助手&#xff0c;以后钓鱼小技巧都可以咨询了。 走过路过&#xff0c;不要错过&#xff0c;快快体验吧~ &#x1f680;&#x1…

【Three.js】知识梳理二十三:Three.js与其他WebGL库与框架对比

在WebGL开发中&#xff0c;Three.js是一个非常流行的库&#xff0c;它简化了3D图形的创建和渲染过程。然而&#xff0c;市场上还有许多其他的WebGL库&#xff0c;如 Babylon.js、PlayCanvas、PIXI.js 和 Cesium&#xff0c;它们也有各自的特点和优势。本文将对Three.js 与这些常…

翻译《The Old New Thing》- The case of the exception that a catch (…) didn’t catch

The case of the exception that a catch (...) didnt catch - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20240405-00/?p109621 Raymond Chen 2024年04月05日 一位客户认为他们修复了一个bug&#xff0c;但他们仍然因为这个bug而崩溃。…