stack_queue的底层,模拟实现,deque和priority_queue详解

文章目录

  • 适配器
  • Stack的模拟实现
  • Queue的模拟实现
  • vector和list的对比
  • deque
    • deque的框架
    • deque的底层
  • priority_queue
    • priority_queue的使用
    • priority_queue的底层
      • 仿函数的使用
      • 仿函数的作用
      • priority_queue模拟实现

适配器

适配器是一种模式,这种模式将类的接口转化为用户希望的另一个接口
可以类比为充电器,将220V转化为你需要的伏数

Stack的模拟实现

函数参数传的是类型和值
模版参数传的是类型

类模版实例化时,按需实例化,你调了哪些函数,就实例化哪些函数,不会全实例化

namespace wbc
{// Container适配转化出Stack,类模版的缺省参数是类型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() const {return _con.back();}bool empty() const {return _con.empty();}size_t size() const {return _con.size();}private:Container _con;// Container会自动调用它的默认构造对于自定义类型来说// 所以不用写};void print_container(){cout << "hello world" << endl;}
}

Queue的模拟实现

队列是先进先出的用list实现更好,vector只支持尾插和尾删,不能直接进行队头的删除

// 队列是队尾进数据队头出数据namespace wbc
{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() const{return _con.front();}const T& back() const{return _con.back();}bool empty() const{return _con.empty();}size_t size() const {return _con.size();}private:Container _con;};
}

vector和list的对比

  • vector
    优点:
    1.尾插尾删不错,支持高效的下标随机访问
    2.物理空间连续,所以高速缓存利用率高
    缺点:
    1.头部和中间的插入和删除效率低
    2.空间需要扩容,扩容有一定的代价(效率和空间浪费)

  • list
    优点:
    1.按需申请释放空间,不需要扩容
    2.支持任意位置的插入和删除
    缺点:
    1.不支持下标随机访问

deque

deque不是先进先出,是任意位置插入删除的容器

deque的框架

deque是vector和list的缝合
这里的扩容是需要扩容指针数组,让中控的指针更多,指向的buff数组更多,如果buff数组不够的话,也要增加buff数组(new buff[ ])

在这里插入图片描述

在这里插入图片描述

deque的底层

  • 底层是两个迭代器,map和map_size
    start和finish的迭代器
    都有指向当前buff数组的cur,指向开始位置的first,指向数据结束位置的下一个位置的last,还有一个指向中控的node
  • start和finish两个迭代器:
    在这里插入图片描述
  • 两个迭代器的图

在这里插入图片描述

  • deque头插头删,尾插尾删效率很高,比vector的效率高,比list开空间上不需要开大量的细碎的空间,空间利用率更高

  • 下标的随机访问还行,比vector稍微差一些,vector是直接+数字到达相应的位置,deque是需要进行10几次运算才能到相应的位置,比如可能头插了,数据需要减去,要计算

  • 中间的插入和删除效率很低,需要挪动数据,是O(N)
    在这里插入图片描述

  • operator++的源码

在这里插入图片描述

priority_queue

优先级队列也不是先进先出的,priority_queue也是一个容器适配器,在queue的头文件下

默认是大的数优先级更高,底层是
堆的底层是vector

在这里插入图片描述

priority_queue的使用

int main()
{// less < 大的优先极高 大堆// greater > 小的优先级高 小堆// priority_queue<int,vector<int>,less<int>> pq;priority_queue<int, vector<int>, greater<int>> pq;pq.push(1);pq.push(2);pq.push(3);pq.push(10);pq.push(9);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;return 0;
}

priority_queue的底层

仿函数的使用

仿函数本质是一个类,这个类重载了operator(),它的对象可以像函数一样使用
仿函数是一个类可以像模版参数一样使用
仿函数很多都是空类,没有成员变量的类,对象大小为1
仿函数控制大堆和小堆,就不需要写一个大堆和一个小堆了

// 仿函数本质是一个类,它重载了operator(),它的对象可以像函数一样使用
template<class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};int main()
{Less<int> A;// 函数对象cout << A(2, 3) << endl;// 底层是cout << A.operator()(2,3) << endl;
}

仿函数的作用

在排序中可以用仿函数不用写两个(一个用于升序,一个用于降序的排序),仿函数的函数对象传参,对象是一个类,用模版参数接收,函数模版要传对象自动推导这个类型,优先级队列的那里是类模版传类型

// < 升序
// > 降序
template<class compare>
void Bubblesort(int* a, int n, compare com)
{for (int i = 0; i < n; i++){// 单趟int flag = 0;for (int j = 1; j < n-i; j++){if(com(a[j],a[j-1]))// if (a[j] < a[j - 1]){swap(a[j], a[j - 1]);flag = 1;}}if (flag == 0) break;}
}
int main()
{Less<int> A;Greater<int> B; 函数对象//cout << A(2, 3) << endl;//   // 底层是//cout << A.operator()(2,3) << endl;int a[] = { 9,1,2,5,7,4,6,3 };// 有名对象Bubblesort(a, 8, A);Bubblesort(a, 8, B);// 匿名对象Bubblesort(a, 8, Less<int>());Bubblesort(a, 8, Greater<int>());
}

在这里插入图片描述
在这里插入图片描述

priority_queue模拟实现

#pragma once
#include<vector>template<class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};namespace wbc
{template<class T, class Container = vector<T>,class Compare = Less<T>>class priority_queue{public:// 默认是大堆void AdjustUp(int child){Compare com;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& x){_con.push_back(x);// 插入数据之后建堆,保证是堆// 向上调整建堆AdjustUp(_con.size() - 1);}// 向下调整建堆void AdjustDown(int parent){// 找出左右孩子中大的那个// 假设左孩子大size_t child = parent * 2 + 1;Compare com;while (child < _con.size()){//                             _con[child] < _con[child+1]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(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();// 向下调整建堆AdjustDown(0);}const T& top(){// 如果为空,容器底层会检查不用管return _con[0];}size_t size() const{return _con.size();}bool empty() const{return _con.empty();}private:Container _con;};
}

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

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

相关文章

LLM - 大模型 ScallingLaws 的 CLM 和 MLM 中不同系数(PLM) 教程(2)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145188660 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…

杰盛微 IRS2336STRPBF 700V带使能和故障报告的三相反逻辑驱动芯片 SOP28封装

IRS2336STRPBF 700V带使能和故障报告的三相反逻辑驱动芯片 IRS2336是 N型高压、高速功率 MOSFET/IGBT高低侧三相栅极驱动芯片&#xff0c;包含三路独立的半桥驱动电路。内部集成了欠压保护和过流保护功能&#xff0c;出现异常时立即关断六通道输出。提供外部使能控制可同时关断…

深入理解第三范式(3NF):数据库设计中的重要性与实践

title: 深入理解第三范式(3NF):数据库设计中的重要性与实践 date: 2025/1/17 updated: 2025/1/17 author: cmdragon excerpt: 在数据库设计中,规范化是确保数据完整性、减少冗余和提高查询效率的关键过程。第三范式(3NF)作为关系数据库设计的高级规范,建立在前两范式…

mongoose 支持https踩坑纪实

简述 mongoose是C编写的嵌入式web服务&#xff0c;它能够支持https协议&#xff0c;可以简单的部署&#xff0c;但要做到完美部署&#xff0c;不是那么容易。 部署方法 本人使用的是最新的7.16版&#xff0c;以前版本似乎是要通过修改 头文件中的 MG_ENABLE_SSL 宏定义&…

RK3576 Android14 状态栏和导航栏增加显示控制功能

问题背景&#xff1a; 因为RK3576 Android14用户需要手动控制状态栏和导航栏显示隐藏控制&#xff0c;包括对锁屏后下拉状态栏的屏蔽&#xff0c;在设置功能里增加此功能的控制&#xff0c;故参考一些博客完成此功能&#xff0c;以下是具体代码路径的修改内容。 解决方案&…

C#高级:通过 Assembly 类加载 DLL 和直接引用DLL的方法大全

一、主项目不添加引用 &#xff08;主项目不添加引用&#xff0c;而是通过路径获取指定dll&#xff09; 1.打印类的属性名称 namespace ReflectionDemo {class Program{static void Main(string[] args){// 指定【编译输出】的项目类库dll&#xff08;启动项目编译输出目录下…

【k8s面试题2025】1、练气期

主要通过呼吸吐纳等方法&#xff0c;将外界的天地灵气吸入体内&#xff0c;初步改造身体&#xff0c;使身体素质远超常人。 文章目录 docker 和虚拟机的不同Kubernetes 和 docker 的关系Kube-proxy IPVS 和 iptables 的异同蓝绿发布Kubernetes中常见的数据持久化方式关于 Docke…

音视频入门基础:RTP专题(4)——FFmpeg源码中,判断某文件是否为SDP文件的实现

一、引言 执行《音视频入门基础&#xff1a;RTP专题&#xff08;2&#xff09;——使用FFmpeg命令生成RTP流》中的“媒体文件转推RTP的FFmpeg命令”会生成一个SDP文件&#xff0c;该文件内容如下&#xff1a; v0 o- 0 0 IN IP4 127.0.0.1 sNo Name t0 0 atool:libavformat 61…

【大数据2025】Hadoop 万字讲解

文章目录 一、大数据通识大数据诞生背景与基本概念大数据技术定义与特征大数据生态架构概述数据存储数据计算与易用性框架分布式协调服务和任务调度组件数仓架构流处理架构 二、HDFSHDFS 原理总结一、系统架构二、存储机制三、数据写入流程四、心跳机制与集群管理 安全模式&…

电脑换固态硬盘

参考&#xff1a; https://baijiahao.baidu.com/s?id1724377623311611247 一、根据尺寸和缺口可以分为以下几种&#xff1a; 1、M.2 NVME协议的固态 大部分笔记本是22x42MM和22x80MM nvme固态。 在京东直接搜&#xff1a; M.2 2242 M.2 2280 2、msata接口固态 3、NGFF M.…

回顾2024年在CSDN的成长

文章目录 我与CSDN的初次邂逅初学阶段的阅读CSDN&#xff1a;编程新手的避风港初学者的福音&#xff1a;细致入微的知识讲解考试复习神器&#xff1a;技术总结的“救命指南”曾经的自己&#xff1a;为何迟迟不迈出写博客的第一步兴趣萌芽&#xff1a;从“读”到“想写”的初体验…

抖音ip属地不准是什么原因?可以改吗

在数字化时代&#xff0c;社交媒体平台如抖音已成为人们日常生活的重要组成部分。随着各大平台对用户隐私和数据安全的日益重视&#xff0c;IP属地的显示功能应运而生。然而&#xff0c;不少抖音用户在使用过程中发现&#xff0c;显示的IP属地与实际位置存在偏差&#xff0c;这…

Win11 安装与配置 Java环境 JDK(以JDK11为例)

0&#xff0c;下载JDK 访问JDK官网&#xff1a;Java Downloads | Oracle 选择对应版本进行下载&#xff0c;目前21和23都是可以直接下载的 但是如果需要下载旧版本&#xff0c;往下拉找到要下载的版本&#xff0c;不过这时候下载就需要登录账号了&#xff0c;注册一个就成 2&…

LabVIEW串口通信调试与数据接收问题

在使用LabVIEW进行串口通信时&#xff0c;常常会遇到无法接收数据的情况。这可能与串口设置、连接、设备响应等多方面因素相关。本文将详细讨论如何使用LabVIEW进行串口通信&#xff0c;并提供常见问题的排查与解决方法&#xff0c;帮助用户更高效地进行数据接收调试。通过调整…

概率扩散去噪模型DDPM

文章目录 摘要abstract高斯噪声扩散模型正向过程逆向过程 论文阅读论文创新点解决的问题 总结参考文献 摘要 本周主要学习了高斯噪声在扩散模型中的应用及相关算法实现。扩散模型受到自然现象的启发&#xff0c;通过在图像中引入高斯噪声&#xff0c;模拟出扩散效果&#xff0…

Python操作Excel——openpyxl使用笔记(3)

3 单元格基本操作 3.1 访问单元格和读写其内容 在前面的例子中&#xff0c;已经简单演示过了向单元格中写入和读取数据。这里进一步提供访问单元格的一些方法。和前面一样&#xff0c;使用工作表的索引方式&#xff0c;可以快速定位一个单元格&#xff1a; import openpyxl w…

2025.1.18机器学习笔记:PINN文献精读

第三十周周报 一、文献阅读题目信息摘要Abstract创新点物理背景网络框架实验实验一&#xff1a;直道稳定流条件实验二&#xff1a;环状网络中的非稳定流条件 结论缺点及展望 二、代码实践总结 一、文献阅读 题目信息 题目&#xff1a;《Enhanced physics-informed neural net…

CSS 的基础知识及应用

前言 CSS&#xff08;层叠样式表&#xff09;是网页设计和开发中不可或缺的一部分。它用于描述网页的视觉表现&#xff0c;使页面不仅实现功能&#xff0c;还能提供吸引人的用户体验。本文将介绍 CSS 的基本概念、语法、选择器及其在提升网页美观性方面的重要性。 什么是 CSS&…

Web开发 -前端部分-CSS-2

一 长度单位 代码实现&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…

Linux shell zip 命令实现不切换当前终端的工作目录打包另一个路径下的文件和文件夹

如图&#xff0c;我想在当前目录 ~/Bypasser 下打包 src 文件夹&#xff0c;使得生成的 zip 压缩包中具有 src 文件夹下的所有文件夹、所有文件夹中的所有子项目、所有文件&#xff0c;保留层次结构但压缩包中最外面不包含 src 这一层。执行命令时&#xff0c;不要改变当前终端…