首页 > 编程语言 >【C++】详细介绍:priority_queue的使用、适配器、deque介绍、仿函数

【C++】详细介绍:priority_queue的使用、适配器、deque介绍、仿函数

时间:2024-11-09 23:44:20浏览次数:3  
标签:deque 模版 适配器 queue vector heap push

目录

一、介绍

二、使用

三、函数模版和类模板的区别

四、适配器

1、适配器适配栈

扩展:

2、deque(双端队列)

缺省模版

五、仿函数


一、介绍

(1)、priority_queue称为优先级队列,是一种容器适配器,不是队列也不是容器。

(2)、该结构的底层是堆结构,默认是大堆,用模版参数来区分是大堆还是小堆。

(3)、具体信息可查看官网手册:https://legacy.cplusplus.com/reference/queue/priority_queue/?kw=priority_queue

二、使用

注意: 如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供> 或者< 的重载。 (1)、大堆使用:
//默认是大堆
priority_queue<int, vector<int>> big_heap;
big_heap.push(1);
big_heap.push(10);
big_heap.push(2);
big_heap.push(4);
big_heap.push(2);
big_heap.push(4);
while (!big_heap.empty())
{
	cout << big_heap.top() << " ";
	big_heap.pop();
}
cout << endl;

(2)、小堆使用,第三个参数模版传大于

//小堆,第三个模版参数用大于
priority_queue<int, vector<int>, greater<int>> small_heap;
small_heap.push(1);
small_heap.push(10);
small_heap.push(2);
small_heap.push(4);
small_heap.push(2);
small_heap.push(4);
while (!small_heap.empty())
{
	cout << small_heap.top() << " ";
	small_heap.pop();
}

三、函数模版和类模板的区别

如下:

sort(s1.begin(), s1.end(), greater<int>());
priority_queue<int, vector<int>, greater<int>>;

看这两段代码的,第一个是sort函数的传参,第二个是类的传参,看第三个参数,看似好像没区别,但实则有个括号的差异,一个传递的是对象,一个传递的是类型

四、适配器

priority_queue的实现是通过适配器实现的,那么什么是适配器呐?

  适配器是一种设计模式,该种模式是将一个类的接口转换成客户希望的另外一个接口。 也就是说,是通过复用对应容器的接口来构成自己想要的结构。适配器的核心是大量复用。  

1、适配器适配栈

先看源代码:

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


HF::stack<int,vector<int>> pq;
pq.push(1);
pq.push(2);
pq.push(3);
pq.push(4);
while (!pq.empty())
{
	cout << pq.top() << " ";
	pq.pop();
}

看代码我们更容易理解适配器的概念,首先用一个类模版,第一个参数T是数据类型,第二个参数Container是具体的容器,为了实现我们需要的结构,必须确保我们所传入的容器有对应的接口:

如上我们实现栈,而栈的核心接口就是插入(push_back),删除(pop_back),取栈顶元素(top),判空(empty),而我们传入的模版是vector类型:

很显然vector都具备这些接口,所以可以用vector适配出一个栈,其步骤就是在栈的相应接口下调用vector对应的接口:

我们知道,因为我们模版传入的是vector,所以成员变量_con就是vector对象,所以就复用相应接口。

扩展:

根据上面内容我们可以思考一个问题:

​​​​​​vector底层是连续的空间,所以适配出的栈就是数组栈,那么当我们传的模版是list,自然而然适配出的就是链式栈。

2、deque(双端队列)

(1)、手册官网: https://legacy.cplusplus.com/reference/deque/deque/?kw=deque (2)、deque是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和 删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比 较高。 (3)、注意:deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维 数组。 (4)、也就是说deque是包含头插头删尾插尾删等一系列接口的东西,相当于把vector和list的优点结合在一起。(但要注意,并不能取代vector和list) 由此我们引出以下内容:

缺省模版

扩展:模版在编译阶段就进行传参。
理解缺省模版,我们可以结合函数参数的缺省值辅助理解。当实参没有传参的时候,形参就会用缺省值,同理,当实参模版没有传参时,就会使用缺省模版,如下:
template<class T ,class Container = deque<T>>

在上述的适配器适配栈中,我们就可以使用deque作为缺省模版,因为deque的接口比较多,所以能实现的结构就更多,模版实参没有传容器时,deque能更加确保提供对应所需的接口。

五、仿函数

C++仿函数的功能类似于C语言中的回调函数,只是C语言用的是函数指针。

通俗讲就是在一个类中重载 () ,然后,哪里需要就在哪里调用。

然后在不同类中实现不同的功能,但都重载(),这时,我们需要哪个功能,就可以传哪个类模版,从而获取该类的功能(如判断大于小于):

举例:

class less
{
public:
	bool operator()(int x,int y)
	{
		return x < y;
	}
};

class greater
{
public:
	bool operator()(int x, int y)
	{
		return x > y;
	}
};

template<class Comapre>
class A
{
public:
	void func(int xx,int yy)
	{
		Comapre _per;
		cout << _per(xx, yy) << endl;
	}
};


int main()
{
	//传入比较小于功能的模版
	A<less> a1;
	a1.func(10, 20);
	//传入比较大于功能的模版
	A<greater> a2;
	a2.func(10, 20);
	return 0;
}

因为类A里面使用了模版,所以我们想使用哪个功能就传入类类型。

标签:deque,模版,适配器,queue,vector,heap,push
From: https://blog.csdn.net/hffh123/article/details/143592086

相关文章

  • [Tricks-00002]CF2026F 操作建树&维护带删deque信息的经典套路
    这怎么是*2700???我大受震撼了好吧。简要题意:有一个初始长度是\(cnt=1\)的序列\(S\),序列每个位置都是若干个二元组\((p,t)\)组成的可重集,初始时\(S_1\)为空集。\(q\)组操作(为修改或询问),有如下四种操作:1x:把\(S_x\)复制到一个新加的点\(S_{++cnt}\)上。2xpt:将\((p......
  • Multi-Scale and Detail-Enhanced Segment Anything-1-LMSA-轻量级多尺度适配器
    `importtorch.nnasnnimporttorchimporttorch.nn.functionalasFclassModifyPPM(nn.Module):definit(self,in_dim,reduction_dim,bins):super(ModifyPPM,self).init()self.features=[]forbininbins:self.features.append(nn.Sequential(nn.Adaptive......
  • C++之queue容器
    queue是C++STL(StandardTemplateLibrary)中的一种容器适配器,用于实现先进先出(FIFO,FirstInFirstOut)的数据结构。queue提供了一组基本的操作来管理队列前端和后端的元素。queue的底层可以基于不同的容器(如deque或list)实现,默认情况下使用deque。主要特点先进......
  • POJ3481 Double Queue (map)
     使用map,并将优先级值放在first以自动排序,如果输入的代码为2,就输出最后一组元素的second并删去,输入代码为3时同理。#include<iostream>#include<map>#include<vector>usingnamespacestd;intmain(void){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);......
  • 实验8:适配器模式
    本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解适配器模式的动机,掌握该模式的结构;2、能够利用适配器模式解决实际问题。[实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。实验要求:1.画出对应的类图;2.提交源代码;3.注意编程规范......
  • 详解Rust标准库:VecDeque 队列
    theme:githubhighlight:an-old-hope查看本地官方文档安装rust后运行rustupdoc查看TheStandardLibrary即可获取标准库内容std::connections::VecDeque定义队列是遵循先入先出规则的线性数据结构,在内存中不一定连续VecDeque定义:可增长的环形缓冲区实现的双端队......
  • Java & Collection/Executor & SynchronousQueue & 总结
    前言 相关系列《Java&Collection&目录》《Java&Executor&目录》《Java&Collection/Executor&SynchronousQueue&源码》《Java&Collection/Executor&SynchronousQueue&总结》《Java&Collection/Executor&SynchronousQueue......
  • 实验8:适配器模式
    [实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。实验要求:1. 对应的类图: 2. 源代码:Cat接口: publicinterfaceCat{  voidcry();  voidcatchMouse();} 实体Cat类: publicclassConcreteCatimplementsCat{    @Over......
  • activemq - queue模式
    特点queue是点对点模式,一条消息对应一个消费者,topic是一对多模式,一条消息可能有一个或多个消费者queue模式消息再发送后消费者可以在之后的任意时间消费,topic模式如果没有订阅者消息就是废消息,会被丢弃。queue模式生产者与消费者之间没有时间相关性,topic模式下生产者和消......
  • 【Orange Pi 5 Linux 5.x 内核编程】-等待队列(WaitQueue)
    等待队列(WaitQueue)文章目录等待队列(WaitQueue)1、等待队列介绍2、等待队列初始化2.1静态初始化2.2动态初始化3、队列任务排队3.1wait_event3.2wait_event_timeout3.3wait_event_cmd3.4wait_event_interruptible3.5wait_event_interruptible_ti......