当前位置: 首页 > news >正文

C++栈、队列、优先级队列模拟+仿函数

 

目录

一、栈的模拟和deque容器

1.deque

1.1deque结构

1.2deque优缺点

2.stack模拟

二、队列的模拟

三、priority_queue优先级队列

1.优先级队列模拟

2.添加仿函数


一、栈的模拟和deque容器

在之前,我们学过了C语言版本的栈,可以看这篇文章 栈和队列。

但是C语言没有模板,我们只能固定一个类型去写,在C++中引入了模板的概念,我们只需要写一份,在调用中给到类型,编译器会自动去帮我们推导是栈里面元素的类型,会非常方便。

1.deque

我们可以看到,库函数里面的栈调用的是一个deque容器。

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

1.1deque结构

首先deque有一个中控数组,这个数据是指针数组,存放的内容是指针,每个指针都指向的一块空间的起始地址。

他的迭代器有  cur(当前数据当前位置)  fisrt(数据起始位置)last(数据结尾位置) node(指向数据的指针)。

头插就去找到最前面的那个有效指针进行头插,尾插就找最后面那个有效指针尾插,遍历就通过迭代器每一个空间块从头遍历到位,就换下一个空间块。

 

1.2deque优缺点

deque实际上是一个缝合怪,他结合了vector和list的内容,将他们糅合在了一起。

优点

与vector比较,deque的优势是 :头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

 但是他也有缺点

deque容器不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list。

那么为何他能在栈和队列中使用,并成为默认容器呢?

因为栈和队列需要尾插,尾删,队列需要尾插,头删deque容器完全可以适配这些需求,因为不需要遍历,并且deque扩容时不需要挪动数据,这也是的deque的效率变高。

2.stack模拟

stack的模拟非常简单,调用模板Container容器的函数就可以了,也不需要迭代器(不用遍历),也不需要构造函数析构函数什么的,因为Container容器是自定义类型,会自动调用的相关构造析构拷贝函数。

#pragma once
#include<deque>
namespace kky
{template<class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};
}

二、队列的模拟

队列模拟跟stack差不都,多了一个back接口,出数据的时候要调用pop_front()

#pragma once
#include<deque>
namespace kky
{template<class T, class Container = deque<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();}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};
}

三、priority_queue优先级队列

优先级队列出数据的时候,会先出优先级高的数据。

如何来判断优先级的高低呢?

这跟你传的数据类型有关,先举个例子

我们插入了   1,10,8,5,6   但出数据的时候缺省按照数据的大小顺序来出的,在这里使用数据的大小来看段他们优先级的高低。

优先级队列出数据时会帮我们做好排序,他的本质就是堆,通过堆的向上向下调整来处理优先级问题。具体堆排序的过程可以看选择排序中的堆排序。

1.优先级队列模拟

优先级队列的模拟实现就是要建堆,每一次插入数据都要进行向上调整,保证是大堆或者小堆。

出数据的时候将第一个数据和最后一个数据互换,再进行尾删,因为第一个数据是我们想要出的数据,将他和最后一个数据交换再尾删,就可以提取出这个数据了,同时现在只有第一个元素不符合小堆或者大堆的情况,其他元素都符合,因此进行一次从索引为0位置的向下调整即可。

namespace kky
{template<class T,class Container = vector<T>>class priority_queue{public:void adjust_up(size_t child){while(child>0){size_t parent = (child - 1) / 2;if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);child = parent;}else{break;}}}void adjust_down(size_t parent){int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _con[child] < _con[child + 1]){child++;}if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up(_con.size()-1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};
}

刚刚的代码构建了一个大堆,但是我们如果想要构建小堆,难不成又要重写一份代码吗?  那必定不是可能的。 

2.添加仿函数

在C语言中,我们可以通过函数指针来处理顺序的问题,但是函数指针类型很繁琐,并且不容易理解,C++推出了仿函数来帮助我们处理这类问题。

写一个类,仅仅重载了operator(),返回类型为bool,在后面进行判断的时候,我们就可以调用这个类对象的(),类似于函数一样,就可以处理了,

template<class T>
class Less
{
public:bool operator()(const T& x1, const T& x2){return x1 < x2;}
};

第一个方式太丑陋了,一般使用第二种方式去调用。

那之前,我们代码中的判断语句,都可以通过调用仿函数更改了 

给模板参数再添加一个类

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

现在就可以开始更改了 

只需要注意顺序即可,需要这样判断的都可以更改,参考如下代码

namespace kky
{template<class T, class Container = vector<T>,class Compare = Less<T>>class priority_queue{public:void adjust_up(size_t child){Compare com;while (child > 0){size_t parent = (child - 1) / 2;if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;}else{break;}}}void adjust_down(size_t parent){Compare com;int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && com(_con[child], _con[child+1])){child++;}if (com(_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);adjust_up(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};
}

 这是我们写的Less仿函数,如果你想让优先级队列建小堆,就可以写再写一个仿函数

template<class T>
class Greater
{
public:bool operator()(const T& x1, const T& x2){return x1 > x2;}
};

需要的时候调用一下即可 

相关文章:

C++栈、队列、优先级队列模拟+仿函数

目录 一、栈的模拟和deque容器 1.deque 1.1deque结构 1.2deque优缺点 2.stack模拟 二、队列的模拟 三、priority_queue优先级队列 1.优先级队列模拟 2.添加仿函数 一、栈的模拟和deque容器 在之前&#xff0c;我们学过了C语言版本的栈&#xff0c;可以看这篇文章 栈和…...

ES挂载不上怎么处理?

全文搜索 EelasticSearch安装 Docker安装 docker run -d --name es7 -e ES_JAVA_POTS"-Xms256m -Xmx256m" -e "discovery.typesingle-node" -v /home/206/es7/data/:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 elasticsearch:7.14.0 …...

问题与分类

设计问题 是否已经有类似的解决方案&#xff0c;是否需要当前的设计设计思路的文档话&#xff0c;背景-》 设计思路-》 好处与不足 -》 其他设计思路的对比&#xff08;淘汰其他设计思路的原因&#xff09; 设计思路的评审&#xff0c;如何评审&#xff0c;如何量化&#xff…...

021-Qt 配置GitHub Copilot

Qt 配置GitHub Copilot 文章目录 Qt 配置GitHub Copilot项目介绍 GitHub Copilot配置 GitHub CopilotQt 前置条件升级QtGitHub Copilot 前置条件激活的了GitHub Copilot账号安装 Neovim 启用插件&#xff0c;重启Qt配置 GitHub Copilo安装Nodejs下载[copilot.vim](https://gith…...

如何使用 PostgreSQL 进行数据迁移和整合?

​ PostgreSQL 是一个强大的开源关系型数据库管理系统&#xff0c;它提供了丰富的功能和灵活性&#xff0c;使其成为许多企业和开发者的首选数据库之一。在开发过程中&#xff0c;经常会遇到需要将数据从一个数据库迁移到另一个数据库&#xff0c;或者整合多个数据源的情况。…...

Qt Signals Slots VS QEvents - Qt跨线程异步操作性能测试与选取建议

相关代码参考&#xff1a;https://gitcode.net/coloreaglestdio/qtcpp_demo/-/tree/master/qt_event_signal 1.问题的由来 在对 taskBus 进行低延迟改造时&#xff0c;避免滥用信号与槽起到了较好的作用。笔者在前一篇文章中&#xff0c;叙述了通过避免广播式地播发信号&…...

Postgres 和 MySQL 应该怎么选?

PostgreSQL和MySQL是两个流行的关系型数据库管理系统&#xff08;DBMS&#xff09;。它们都具有一些相似的功能&#xff0c;但也有一些区别。 在选择使用哪个DBMS时&#xff0c;需要考虑多个因素&#xff0c;包括性能、可扩展性、安全性、功能丰富度、生态系统支持等。下面是对…...

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】 1、概述2、实验环境3、 物品说明4、参考资料与自我总结5、实验过程1、创建目录2、克隆下载文件3、 拉取子目录安装和交叉编译工具链等其他工具4、添加环境变量6、将样例文件拷贝到桌面…...

我终于搞明白了HTTPS协议了!超长文章!

HTTPS协议是现代互联网中非常重要的一种安全协议&#xff0c;它能够在客户端和服务器之间建立一条安全的通信渠道&#xff0c;确保用户的隐私和数据安全。下面我来详细介绍HTTPS协议的相关知识。 HTTP协议的缺点 HTTP协议是互联网中的一种应用层协议&#xff0c;它负责客户端…...

Golang Testify介绍

简介 Golang是一种编译型语言&#xff0c;由Google开发&#xff0c;已经成为了Web开发领域中非常受欢迎的语言之一。在Golang生态系统中&#xff0c;有许多用于编写测试的框架和库&#xff0c;其中Testify是其中一个非常流行的测试框架。 Testify是一个用于编写测试的扩展包&…...

DALL·E 3怎么用?DALL·E 3如何申请开通 ?DALL·E 3如何免费使用?AI绘画教程来喽~

一、引言 DALLE 3 是 OpenAI 在上个月&#xff08;2023 年 9 月&#xff09;发布的一个文生图模型。 相对于 Midjourney 以及 Stable Diffusion&#xff0c;DALLE 3 最大的便利之处在于&#xff0c;用户不需要掌握 Prompt 的写法了&#xff0c;直接自然语言描述即可。 甚至还…...

安装 Dispatch 库

首先&#xff0c;我们需要安装 Dispatch 库。在命令行中运行以下命令来安装 Dispatch&#xff1a; $ sbt console然后&#xff0c;在 Scala 控制台中&#xff0c;导入所需的库&#xff1a; import dispatch._接下来&#xff0c;我们需要设置代理服务器。在 Dispatch 中&#…...

【Unity程序技巧】异步保险箱管理器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…...

ChatGPT 助力英文论文翻译和润色

文章目录 一、前言二、主要内容1. 中英互译2. 中文润色3. 英文润色 三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 随着全球化的推进&#xff0c;跨文化交流变得越来越重要。在学术领域&#xff0c;英文论文的质量对于研究成果的传…...

【2024秋招】腾讯云智武汉后端开发一面 2023-9-20

1 java 1.1 hashMap 1.2 哈希冲突的解决方法 1.3 讲解一下CAS的aba问题 1.4 concurrentHashMap的并发方案为什么要使用cas ConcurrentHashMap 是 Java 并发包 java.util.concurrent 中的一个重要组件&#xff0c;用于提供高并发、高性能、线程安全的哈希映射。为了达到这样…...

k8s-----16、配置管理-ConfigMap

ConfigMap 1、作用2、以volume形式进行挂载2.1 创建配置文件2.2 创建ConfigMap文件2.3 最终的yaml文件 3、以变量形式进行挂载3.1 创建configmap文件3.2 书写最终yaml文件 1、作用 存储不加密的数据到etcd中&#xff0c;以变量或者volume形式挂载到pod的容器中场景&#xff1a…...

QML QTP0001 not set 警告

使用QML的时候发现有这个警告。查阅资料之后发现解决办法。 大概的意思是说现在:/qt/qml/ 这个前缀是QML模块资源文件的前缀&#xff0c;而之前是:/ 这是从QT6.5开始的&#xff0c;旧的前缀被标记为废弃的。文档还说在使用qt_add_qml_module()不指定RESOURCE_PREFIX是新版的前…...

Mac M1编译 swift 5.8.1源码

参考链接&#xff1a;https://github.com/apple/swift/blob/main/docs/HowToGuides/GettingStarted.md#system-requirements 编译 Swift 5.8 源码-六虎 解决M1芯片的Homebrew安装问题--For M1使用者_m1 homebrew安装_a_52hz的博客-CSDN博客 建议全程梯子 一、检查和配置环境…...

[极客大挑战 2019]EasySQL

【解题思路】 1.打开靶机链接 2.输入数据进行尝试 输入1,1&#xff1a; 可以在导航栏里面看到username和password的变量。 3.使用万能密码 username&#xff1a;1 or 11# username&#xff1a;任意数据 password&#xff1a;任意数据 …...

统信UOS技术开放日:四大领域全面接入AI大模型能力

1024是程序员的节日&#xff0c;10月24日&#xff0c;统信举办2023统信UOS技术开放日暨deepin Meetup北京站活动&#xff0c;发布与大模型同行的UOS AI、浏览器AI助手、邮箱AI助手、自然语言全局搜索、畅写在线等多项最新AI技术与产品应用。 统信软件高级副总经理、CTO、深度社…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...