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

server/2025/1/16 15:16:19/

文章目录

适配器

适配器是一种模式,这种模式将类的接口转化为用户希望的另一个接口
可以类比为充电器,将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_122">deque

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

deque_126">deque的框架

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

在这里插入图片描述

在这里插入图片描述

deque_134">deque的底层

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

在这里插入图片描述

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

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

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

  • operator++的源码

在这里插入图片描述

queue_157">priority_queue

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

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

在这里插入图片描述

queue_165">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;
}

queue_192">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>());
}

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

queue_280">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.ppmy.cn/server/158844.html

相关文章

9.7 visual studio 搭建yolov10的onnx的预测(c++)

1.环境配置 在进行onnx预测前&#xff0c;需要搭建的环境如下: 1.opencv环境的配置&#xff0c;可参考博客:9.2 c搭建opencv环境-CSDN博客 2.libtorch环境的配置&#xff0c;可参考博客&#xff1a;9.4 visualStudio 2022 配置 cuda 和 torch (c)-CSDN博客 3.cuda环境的配置…

庖丁解java(一篇文章学java)

(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念... 当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢? 请看下文... 关于决定开始写博文的介绍 …

基于微信小程序的食堂线上预约点餐系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

蓝桥杯刷题第二天——背包问题

题目描述 有N件物品和一个容量是V的背包。每件物品只能使用一次。第i件物品的体积是Vi价值是Wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&#xff0c;N&#xff0c;V&am…

AWS云计算概览(自用留存)

目录 一、云概念概览 &#xff08;1&#xff09;云服务模型 &#xff08;2&#xff09;云计算6大优势 &#xff08;3&#xff09;web服务 &#xff08;4&#xff09;AWS云采用框架&#xff08;AWS CAF&#xff09; 二、云经济学 & 账单 &#xff08;1&#xff09;定…

RK356x bsp 5 - 海华AW-CM358SM Wi-Fi/Bt模组调试记录

文章目录 1、环境介绍2、目标3、海华AW-CM358SM3.1、基本信息3.2、支持SDIO3.03.3、电气特性 4、适配流程步骤5、SDIO控制器适配5.1、sdio dts配置5.2、验证 6、Wi-Fi 适配6.1、wifi dts配置6.2、驱动移植6.2.1、kernel menuconfig6.2.2、传统驱动移植6.2.3、RK SDK WIFI/BT驱动…

如何创建表格式布局

文章目录 1. 概念介绍2. 使用方法3. 示例代码4. 经验总结我们在上一章回中介绍了Image Widget,本章回中将介绍GirdView这种Widget,闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 在Flutter中使用GirdView表示网格状的布局,类似日常办公中使用的Excel,它和ListView一样具…

k8s基础(6)—Kubernetes-存储

Kubernetes-存储概述 k8s的持久券简介 Kubernetes的持久卷&#xff08;PersistentVolume, PV&#xff09;和持久卷声明&#xff08;PersistentVolumeClaim, PVC&#xff09;为用户在Kubernetes中使用卷提供了抽象。PV是集群中的一块存储&#xff0c;PVC是对这部分存储的请求。…