【C++】栈和队列、优先级队列、适配器原理

news2024/12/23 14:05:46

目录

一.栈和队列相关接口

二.适配器介绍

三.栈和队列模拟实现

四.deque介绍

五.优先级队列

六.优先级队列的模拟实现

1.基本结构

2.插入删除操作


一.栈和队列相关接口

1.栈(Stack)的接口

由于栈接口只能支持栈顶插入(入栈),栈顶删除(出栈),因此接口很少,这里都是熟悉的接口 。如果对于栈和队列不熟悉,可以参考我之前用C语言实现栈和队列的深度解析: 

【数据结构】栈和队列-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/2301_80555259/article/details/138817611

2.队列(Queue)的接口

队列相比于栈只多了一个接口:back,用于取队尾数据,队列的front相当于栈的top 


二.适配器介绍

无论是栈还是队列,其模板参数中都有一个Container,缺省值为deque<T>,这里就要引入一个叫做“适配器”的概念

 

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

一个非常典型的例子就是插头的适配器:

那么在数据结构中,这种适配器是什么呢?

在C语言实现栈时,我们实现栈的底层实际上是顺序表,也就是把顺序表做了一层封装和限制,让它的功能变得和栈一样,这里C++也是同理:在实现栈的时候不用再去手搓一个顺序表,可以直接调用库里的vector类! 


三.栈和队列模拟实现

和标准库里的模板一样,由于栈要复用其他数据结构,所有在定义模板时有两个模板参数

//deque后续会解释
template<class T, class Container = deque<T>>
class Stack
{
	//......
private:
	Container _con;
}

这样实现栈就会非常方便,不用写构造函数和析构函数,因为默认生成的构造和析构会去调用内嵌类型的构造和析构帮助我们完成任务

//注:以下的push_back和 back等都是vector中的
void push(const T& val)
{
	_con.push_back(val);
}

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

T& top()//可读可写
{
	return _con.back();
}

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

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

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

 栈的实现就完成了,至于队列是很相似的,这里就不再继续实现队列了。


四.deque介绍

deque又被称作双端队列,是一种双开口的“连续”空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,同时时间复杂度都为O(1),与vector比较,头插效率高,不需要频繁挪动元素,而与list相比则空间利用率比较高 

  接下来看看deque的对应接口:

可以发现deque不仅既有头插尾插,头删尾删,并且还支持方括号[]访问 ,难道它底层也是连续的物理空间吗?

 其实deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际上deque类似于一个动态的二维数组,其底层结构如下图:

注意deque有一个中控数组的概念,deque扩容就是直接开辟一份空间,再让中控数组指向新开辟的空间,再将原先空间的内容拷贝至新空间 


五.优先级队列

priority_queue(优先级队列)简单介绍

  1. 优先级队列是一种容器适配器,它的第一个元素总是它包含的元素中最大的(默认是大堆)
  2. 类似于堆,在堆中可以随时插入元素,并始终在内部保持堆的结构,只能检索最大堆元素(优先级队列中位于最顶部的元素)
  3. 底层容器可以是任何标准的容器类模板,不过容器需要支持随机迭代器(random access iterator)以及以下功能:
  • empty():检测容器是否为空
  • size():返回容器中有效元素个数
  • front():返回容器中第一个元素的引用
  • push_back():在容器尾部插入元素

    vector类和deque类都满足这些需求,默认情况下,若没有指定容器,则默认使用vector

优先级队列默认有三个模板参数,第三个就是来决定此优先级队列是大堆还是小堆,它叫仿函数,会下一篇文章讲解,这里先不管它,我们需要做到的是,默认的less是大堆,若我们显式传参greater,那么就是小堆  

优先级队列的接口

函数功能
priority_queue()构造一个空的优先级队列
priority_queue(first, last)用迭代器区间构造一个优先级队列
empty()检测是否为空
top()返回优先级队列中最大(最小)元素,即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素

六.优先级队列的模拟实现

1.基本结构

template<class T, class Container = vector<T>>
class Priority_queue
{
public:
	//成员函数
private:
	Container _con;//此容器默认是vecto
};

2.插入删除操作

由于优先级队列实际上就是一个堆,所以在插入删除之后要进行向上调整或向下调整以保持堆的结构,那么对应的操作就很熟悉了

//向上调整
void AdjustUp(int* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//向下调整
void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (a[child+1] < a[child] && child + 1 < n)
		{
			child++;
		}
		if (a[child] < a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//堆的插入
void push(const T& val)
{
	_con.push_back(val);
	adjust_up(_con.size() - 1);
}

//堆的删除
void pop()
{
	std::swap(_con[0], _con[_con.size() - 1]);
	_con.pop_back();
	adjust_down(0);
}

 插入和删除可谓是和堆一模一样的做法,其余的函数接口也都是如此,这里就不过多实现了,明白了优先级队列的大致原理即可


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

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

相关文章

【C语言版】数据结构教程(二)线性表

【内容简介】本文整理数据结构&#xff08;C语言版&#xff09;相关内容的复习笔记&#xff0c;供各位朋友借鉴学习。本章内容更偏于记忆和理解&#xff0c;请读者们耐心阅读。同时&#xff0c;这里提醒各位读者&#xff0c;尽管书本上说本书用的是 C 语言版&#xff0c;但是中…

基于javaweb的茶园茶农文化交流平台的设计与实现(源码+L文+ppt)

springboot基于javaweb的茶园茶农文化交流平台的设计与实现&#xff08;源码L文ppt&#xff09;4-20 系统功能结构 系统结构图可以把杂乱无章的模块按照设计者的思维方式进行调整排序&#xff0c;可以让设计者在之后的添加&#xff0c;修改程序内容的过程中有一个很明显的思维…

使用 WebStorm 导入已有的 Vue 项目并运行的步骤与注意事项

目录 1. 引言2. WebStorm 环境准备2.1 安装 WebStorm2.2 配置 Node.js 和 npm2.3 使用 nvm 管理 Node.js 和 npm 版本2.4 npm 版本与 Vue 版本对应关系 3. 导入已有的 Vue 项目3.1 打开 Vue 项目3.2 安装项目依赖3.3 使用 nvm 控制 Node.js 和 npm 版本 4. 运行 Vue 项目4.1 启…

STM32双轮平衡小车(基于STM32F103C8T6HAL库)

STM32双轮平衡小车参考教程 这个项目是跟做以上UP的STM32双轮平衡小车&#xff0c;主要是为了学习电机驱动和PID控制。这篇我就不提供源码了&#xff0c;我也是跟学的&#xff0c;原作者也提供了源码&#xff0c;我记录一下自己的理解。 1 PID原理 1.1 PID简介 1.2 PID演示 …

打破AI壁垒-降低AI入门门槛

AI和AGI AI&#xff08;人工智能-Artificial Intelligence&#xff09;&#xff1a; 先说说AI&#xff0c;这个大家可能都不陌生。AI&#xff0c;就是人工智能&#xff0c;它涵盖了各种技术和领域&#xff0c;目的是让计算机模仿、延伸甚至超越人类智能。想象一下&#xff0c;…

图像分割分析效果2

这次加了结构化损失 # 训练集dice: 0.9219 - iou: 0.8611 - loss: 0.0318 - mae: 0.0220 - total: 0.8915 # dropout后&#xff1a;dice: 0.9143 - iou: 0.8488 - loss: 0.0335 - mae: 0.0236 - total: 0.8816 # 加了结构化损失后:avg_score: 0.8917 - dice: 0.9228 - iou: 0.…

如何做服务迁移、重构?

思维导图 0. 前言 本文意在提供服务迁移的完整思路&#xff0c;将思考题变成填空题&#xff0c;只需要按照本文提供的思路填空&#xff0c;服务迁移至少可以做到 80 分。 本文的服务迁移指&#xff1a;将老服务的代码迁移至新服务。 1. 服务资源梳理 服务资源&#xff0c;我…

AI学习记录 - 旋转位置编码

创作不易&#xff0c;有用点赞&#xff0c;写作有利于锻炼一门新的技能&#xff0c;有很大一部分是我自己总结的新视角 1、前置条件&#xff1a;要理解旋转位置编码前&#xff0c;要熟悉自注意力机制&#xff0c;否则很难看得懂&#xff0c;在我的系列文章中有对自注意力机制的…

Win32函数调用约定(Calling Convention)

平常我们在C#中使用DllImportAttribute引入函数时&#xff0c;不指明函数调用约定(CallingConvention)这个参数&#xff0c;也可以正常调用。如FindWindow函数 [DllImport("user32.dll", EntryPoint"FindWindow", SetLastError true)] public static ext…

来啦| LVMH路威酩轩25届校招智鼎高潜人才思维能力测验高分攻略

路威酩轩香水化妆品(上海)有限公司是LVMH集团于2000年成立&#xff0c;负责集团旗下的部分香水化妆品品牌在中国的销售包括迪奥、娇兰、纪梵希、贝玲妃、玫珂菲、凯卓、帕尔马之水以及馥蕾诗等。作为目前全球最大的奢侈品集团LVMH 集团秉承悠久的历史&#xff0c;不断打破常规&…

群晖最新版(DSM 7.2) 下使用 Web Station 部署 flask 项目

0. 需求由来 为了在 DSM 7.2 版本下的群晖 NAS 里运行我基于 flask 3.0.2 编写的网页应用程序&#xff0c;我上网查了非常多资料&#xff0c;也踩了很多坑。最主要的就是 7.2 版本的界面与旧版略有不同&#xff0c;而网络上的资料大多基于旧版界面&#xff0c;且大部分仅仅说明…

记忆化搜索【下】

375. 猜数字大小II 题目分析 题目链接&#xff1a;375. 猜数字大小 II - 力扣&#xff08;LeetCode&#xff09; 题目比较长&#xff0c;大致意思就是给一个数&#xff0c;比如说10&#xff0c;定的数字是7&#xff0c;让我们在[1, 10]这个区间猜。 如果猜大或猜小都会说明…

2024AI绘画工具排行榜:探索最受欢迎的AI绘图软件特点与选择指南

AI绘画工具各有优势&#xff0c;从开放性到对特定语言和文化的支持&#xff0c;以及对图像细节和艺术性的不同关注点&#xff0c;根据具体需求选择合适的工具 MidJourney 图片品质卓越&#xff0c;充满独特创意&#xff0c;初期能够免费获取数十账高质量图片&#xff0c;整个生…

C++20中支持的非类型模板参数

C20中支持将类类型作为非类型模板参数&#xff1a;作为模板参数传入的对象具有const T类型&#xff0c;其中T是对象的类型&#xff0c;并且具有静态存储持续时间(static storage duration)。 在C20之前&#xff0c;非类型模板参数仅限于&#xff1a;左值引用类型、整数类型、指…

VMware Fusion Pro 13 Mac版虚拟机 安装Win11系统教程

Mac分享吧 文章目录 Win11安装完成&#xff0c;软件打开效果一、VMware安装Windows11虚拟机1️⃣&#xff1a;准备镜像2️⃣&#xff1a;创建虚拟机3️⃣&#xff1a;虚拟机设置4️⃣&#xff1a;安装虚拟机5️⃣&#xff1a;解决连不上网问题 安装完成&#xff01;&#xff0…

用Pytho解决分类问题_DBSCAN聚类算法模板

一&#xff1a;DBSCAN聚类算法的介绍 DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff09;是一种基于密度的聚类算法&#xff0c;DBSCAN算法的核心思想是将具有足够高密度的区域划分为簇&#xff0c;并能够在具有噪声的空间数据库中发…

关于SpringMVC的理解

1、SpringMVC 应用 1.1、简介 1.1.1、MVC 体系结构 三层架构&#xff1a; 我们的开发架构⼀般都是基于两种形式&#xff0c;⼀种是 C/S 架构&#xff0c;也就是客户端/服务器&#xff1b;另⼀种是 B/S 架构&#xff0c;也就是浏览器服务器。在 JavaEE 开发中&#xff0c;⼏乎…

陪护系统|陪护系统源码|护理陪护小程序

随着医疗水平的不断提高&#xff0c;人们对护理服务的需求也越来越高。为了更好地满足患者和家属的需求&#xff0c;陪护系统定制开发应运而生。 陪护系统定制开发是根据医疗机构的实际需求&#xff0c;设计并开发一套专门用于陪护服务的系统。该系统拥有一系列丰富的功能&…

基于人工智能的图片生成系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图片生成是计算机视觉领域的一个重要任务&#xff0c;基于生成对抗网络&#xff08;GAN&#xff09;的图片生成系统能够从噪声中生成逼…

大数据-119 - Flink Window总览 窗口机制-滚动时间窗口-基于时间驱动基于事件驱动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…