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

C++容器适配器的模拟实现-stack、queue、priority_queue

###

容器适配器是将容器转换到其他容器自身不方便使用的地方,但是就容器适配器其本身还是包装的容器,所以这个类模板中各个接口的实现都是调用的容器的接口,因为容器适配器可能适配多个容器,所以这个类模板的模板参数中有一个参数是代表容器类型的,方便传参过来能及时改变;

一、stack的模拟

这是这个类模板的模板,那么我们也模拟这样实现,首先解读,T是stack里面存放的数据类型,Container是stack里面包装的容器的类型,默认是deque,这是因为deque这个容器不仅兼顾了vector和list的基本接口,并且deque相比于vector不需要浪费过多空间、头删头插的效率高,相比于list的缓存利用率更高,这个和deque的底层结构有关;

###stack实现的代码:

#pragma once
#include<deque>
#include<list>
#include<vector>
using namespace std;
namespace S
{template<class T,class Container = deque<T>>class Stack{public:Stack()//调用Container的默认构造函数{}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& top()const{return _con.back();}void push(const T& val = T()){_con.push_back(val);}void pop(){_con.pop_back();}private:Container _con;};
}

首先stack对于vector、list、deque都能作为它们的适配器,所以头文件包含了这几个容器;

其次看到这个模板类的成员变量,是一个Container,代表容器类型,这个容器类型默认为deque,用这个类型去定义一个容器作为stack这个适配器的成员变量,那么在实现stack的接口时,就直接调用容器_con的接口;

###测试:

void test1()
{Stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);cout << "数据个数:" << st.size() << endl;cout << "是否为空:" << st.empty() << endl;cout <<"栈顶数据:"  << st.top() << endl;st.pop();cout << "数据个数:" << st.size() << endl;cout << "栈顶数据:" << st.top() << endl;
}

注意在源文件中测试时要包含实现stack的头文件,并且展开命名空间;

###运行结果:

二、queue的模拟

和stack大差不差,注意它不能作为vector的适配器,队列queue的头删(出队列)的接口要调用pop_front,而vector没有这个接口,所以不能;

###代码:

namespace Q
{template<class T ,class Container = deque<T>>class Queue{public:Queue(){}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& front()const{return _con.front();}const T& back()const{return _con.back();}void push(const T& val=T()){_con.push_back(val);}void pop(){_con.pop_front();}private:Container _con;};
}

 ###测试:

void test2()
{Queue<int> q;for (int i = 1; i <= 5; i++){q.push(i);}cout << "是否为空:" << q.empty() << endl;cout << "数据个数:" << q.size() << endl;cout << "队头数据:" << q.front() << endl;cout << "队尾数据:" << q.back() << endl;q.pop();//删除队头数据cout << "队头数据:" << q.front() << endl;
}

注意Queue<int> q;可以显示传它的容器类型,stack也是一样;

###运行结果:

三、priority_queue的模拟

这个是优先级队列,它的其他地方和queue一样,就是队头的元素一直是最大的或者是最小的,它的底层实现有堆的部分,大堆的堆顶也就是最大的,小堆的相反;所以在实现时涉及到堆的向上和向下调正的方法;

另外,我们要写一份类模板,这个类模板要求可以通过接收不同的模板参数来调正这个优先级队列是通过大堆实现的还是通过小堆实现的 ,这也是库里面的实现方法;也就是说,这个适配器的模板参数中要包含一个类型,这个类型实例化出来的对象作为适配器的成员变量(和_con类似),并且这个对象可以调用自己的函数来实现更大或者更小的比较,这里需要使用仿函数;

所谓的仿函数就是重载()的函数;

直接看实现的代码来解读

###代码实现:

namespace Q
{	
//仿函数重载()template<class T>class Less{public:bool operator()(T& x, T& y){return x < y;}};template<class T>class Greater{public:bool operator()(T& x, T& y){return x > y;}};template<class T,class Container =vector<T>,class Compare = Less<T>>class Priority_Queue{public:Priority_Queue(){}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& top()const{return _con[0];}void AdjustUp(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (child >= 0){if(_com(_con[parent],_con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& val = T()){_con.push_back(val);AdjustUp();//向上调正建堆}void AdjustDown(){int parent = 0;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[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){assert(_con.size());swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown();}private:Container _con;Compare _com;//调用仿函数就直接_com(),相当于_com.operator();};}

第二个模板参数是vector这是因为里面有top的接口,而vector也有; 

首先看到类Less和Greater,里面有成员函数,都是重载的()的函数,也就是仿函数,包装成一个类是因为类可以作为类型传到模板参数中;

看到优先级队列的类模板的实现,第三个模板参数就是上面封装的类,这个默认是Less,在看到优先级队列的成员变量,除了我们已近知道的_con,还有一个_com,这是通过Less实例化出来的对象,这个对象可以直接在后面加上()来调用它自己的成员函数,那么就可以来进行比较了;

其他的接口很平常,看到push和pop的接口,首先push,要进行向上调整,里面使用_com(),就是比较父节点和子节点,父节点更小就和子节点交换,实现大堆;pop删除是先交换队头和队尾的数据再pop_back(),相当于删除了队头的节点,之后再进行向下调整,把次大的换到根节点处;

只有涉及到父节点和子节点比较大小时才用到_com(),这是因为这个函数的比较决定了是大堆还是小堆,当传Less<T>时就是大堆;传Greater时就是小堆(把更大的换到了子节点);

###测试:

void test3()
{Priority_Queue < int,vector<int>> pq;pq.push(1);pq.push(2);pq.push(3);pq.push(4);pq.push(5);pq.pop();cout << "是否为空:" << pq.empty() << endl;cout << "数据个数:" << pq.size() << endl;cout << "队头数据:" << pq.top() << endl;//也是堆顶数据
}

###运行结果

push走完 

 

pop走完

可以观察到这就是按照堆的规则调整的; 

相关文章:

C++容器适配器的模拟实现-stack、queue、priority_queue

### 容器适配器是将容器转换到其他容器自身不方便使用的地方&#xff0c;但是就容器适配器其本身还是包装的容器&#xff0c;所以这个类模板中各个接口的实现都是调用的容器的接口&#xff0c;因为容器适配器可能适配多个容器&#xff0c;所以这个类模板的模板参数中有一个参数…...

fastapi的docs页面是空白解决

环境&#xff1a;openEuler、python 3.11.6、fastapi 0.115.2 背景&#xff1a;居家办公&#xff0c;默认搭建的fastapi的docs接口为空白 时间&#xff1a;20241016 说明&#xff1a;网上很多教程的缺点是复杂&#xff08;但是能够了解的更清楚&#xff09;&#xff0c;使用…...

浙大数据结构:11-散列4 Hashing - Hard Version

这道题主要在于思路&#xff0c;感觉像个模拟题&#xff0c;用到了线性探测的算法 机翻 1、条件准备 visit数组看这个位置有没有放进来数&#xff0c;num存非负整数&#xff0c;s存未到放入时机的数。 answer存答案。n为总共数量。 #include <iostream> #include<…...

pm2 守护http-server

PM2&#xff08;Process Manager 2&#xff09;是一个用于Node.js应用程序的进程管理器。以下是使用PM2守护HTTP服务器的步骤&#xff1a; 1. 安装PM2 如果你还没有安装PM2&#xff0c;可以使用以下命令安装&#xff1a; npm install pm2 -g 2. 启动HTTP服务器 你需要一个HTT…...

国外电商系统开发-运维系统应用管理

还记得您常用的 service httpd start 、service sshd stop这样的命令吗&#xff1f;这些都是在停止启动服务&#xff0c;为了让研发人员&#xff0c;或者是快速操作服务&#xff0c;这里给大家制定了简单的应用管理。在这里&#xff0c;您可以把上面的命令加入进来&#xff0c;…...

剖析线程池实现原理

前置推荐阅读&#xff1a;java并发之线程池使用-CSDN博客 自定义实现一个带监控的线程池 首先我们继承ThreadPoolExecutor&#xff0c;实现构造函数以及重写beforeExecute和afterExecute两个函数&#xff0c;具体调用我们会在代码实现层面进行详细的分析。 import java.util.…...

【中危】Oracle TNS Listener SID 可以被猜测

一、漏洞详情 Oracle 打补丁后&#xff0c;复测出一处中危漏洞&#xff1a;Oracle TNS Listener SID 可以被猜测。 可以通过暴力猜测的方法探测出Oracle TNS Listener SID&#xff0c;探测出的SID可以用于进一步探测Oracle 数据库的口令。 建议解决办法&#xff1a; 1. 不应该使…...

三维测量与建模笔记 - 简介

计算机视觉相关主题 主要有两个最主要的层面&#xff0c;几何和语义。几何层面描述了客观事实&#xff0c;比如物体的距离、大小、形状、位置等。语义层面则是从人类抽象出的概念出发&#xff0c;描述了物体是什么、行为是什么、为什么&#xff0c;比如自动驾驶场景中识别出信号…...

Glide 简易教程

文章目录 1 引入依赖2 图片形状2.1 圆形 CircleCrop2.2 旋转 Rotate2.3 圆角 RoundedCorners2.4 自定义圆角 GranularRoundedCorners 1 引入依赖 implementation("com.github.bumptech.glide:glide:4.16.0")2 图片形状 2.1 圆形 CircleCrop Glide.with(this).load…...

flutter 使用三方/自家字体

将字体放入assets/fonts下 在pubspec.yaml文件中flutter下添加如下代码&#xff1a; flutter:fonts:- family: MyCustomFontfonts:- asset: assets/fonts/MyCustomFont.ttf 在flutter Text widget中使用字体 import package:flutter/material.dart;void main() > runApp(…...

2024台州赛CTFwp

备注&#xff1a; 解题过程中&#xff0c;关键步骤不可省略&#xff0c;不可含糊其辞、一笔带过。解题过程中如是自己编写的脚本&#xff0c;不可省略&#xff0c;不可截图&#xff08;代码字体可以调小&#xff1b;而如果代码太长&#xff0c;则贴关键代码函数&#xff09;。…...

词根plac-和place、please

英文有一个词根和单词place(v.放&#xff0c;放置 n.位置&#xff0c;地方&#xff1b;位&#xff0c;职位)长得很像&#xff0c;这个词根就是plac-&#xff0c;它有两个语义&#xff1a;高兴&#xff0c;愉悦&#xff1b;平静&#xff0c;抚平。 其实&#xff0c;place这个单…...

ubuntu下route命令详解

buntu下route命令详解 1、显示路由表 route -n2、临时路由设置&#xff0c;重启网卡失效#添加一条路由(发往192.168.62这个网段的全部要经过网关192.168.1.1)route add -net 192.168.62.0 netmask 255.255.255.0 gw 192.168.1.1#删除一条路由 删除的时候不用写网关route del …...

13.java面向对象:面向对象的三大特征

java面向对象&#xff1a;面向对象的三大特征 面向对象的三大特征1.封装get和set规范属性的合法化 2.继承类继承子类调用父类方法super的用法通过super调用父类public的属性super注意点super对比this 方法重写静态方法中奇怪的现象非静态方法 3.多态多态存在的条件多态中成员访…...

【VUE】Vue中的内置组件

Vue2中的内置组件&#xff1a; <component>&#xff1a;动态组件&#xff0c;可以根据传递的 is 属性值渲染不同的组件。<transition>&#xff1a;过渡动画组件&#xff0c;可以在元素插入、更新或移除时添加动画效果。<transition-group>&#xff1a;过渡动…...

若依框架篇-若依框架搭建具体过程、后端源代码分析、功能详解(权限控制、数据字典、定时任务、代码生成、表单构建、接口测试)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 若依框架概述 1.1 若依构建 1.2 后端项目搭建 1.3 前端项目搭建 2.0 利用若依框架生成前后端代码案例 3.0 功能详解 3.1 功能详解 - 权限控制 3.1.1 使用权限控制…...

恢复已删除文件的 10 种安卓数据恢复工具

由于我们现在在智能手机上存储了大量重要文件&#xff0c;因此了解数据恢复工具变得很重要。您永远不会知道什么时候需要使用 安卓 数据恢复工具。 由于不乏 Windows 数据恢复工具&#xff0c;因此从崩溃的计算机中恢复文件很容易。但是&#xff0c;当涉及到从 安卓恢复数据时…...

Internet Download Manager2025快速下载,新功能解锁!

&#x1f31f;下载界的“速度与激情”&#xff1a;Internet Download Manager超燃体验&#xff01;&#x1f525; 嘿&#xff0c;各位小伙伴们&#xff01;&#x1f44b;今天我要来给你们安利一个让我上网冲浪效率翻倍的神奇软件——Internet Download Manager&#xff08;简称…...

传感器应用注意事项

一、通断型传感器 多数活动部件可直接作为导电材料的传感器为通断型传感器&#xff0c;在受力的条件下&#xff0c;其两个引脚的通断状态会发生改变。 常见通断型传感器 单通道按键多通道按键拨码开关接线帽磁力开关轻触开关… 通断型传感器无需供电&#xff0c;其控制环路…...

PayPal美区账号注册指南

PayPal作为一种便捷的在线支付方式&#xff0c;受到了广大用户的青睐。特别是对于那些需要在美国购物或者进行交易的人来说&#xff0c;注册并正确使用美国地区的PayPal账户显得尤为重要。本次小编会教大家如何注册和使用美区PayPal账户&#xff0c;并讨论是否需要“养号”的问…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...