C++初阶:容器适配器priority_queue常用接口详解及模拟实现、仿函数介绍

news2024/12/29 16:38:11

介绍完了stack和queue的介绍以及模拟的相关内容后:C++初阶:容器适配器介绍、stack和queue常用接口详解及模拟实现
接下来进行priority_queue的介绍以及模拟:


文章目录

  • 1.priority_queue的介绍和使用
    • 1.1priority_queue的初步介绍
    • 1.2priority_queue的使用
    • 1.3进一步补全介绍
  • 2.仿函数/函数对象讲解
  • 3.模拟priority_queue
    • 文件规划和一览
    • 3.1模拟priority_queue(priority_queue.h)
    • 3.2测试(test.cpp)


1.priority_queue的介绍和使用

1.1priority_queue的初步介绍

image-20240130191313960

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的(默认是大堆)

  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)

  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。

  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

  • empty():检测容器是否为空
  • size():返回容器中有效元素个数
  • front():返回容器中第一个元素的引用
  • push_back():在容器尾部插入元素
  1. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。

  2. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

1.2priority_queue的使用

image-20240130192200400

函数声明接口说明
priority_queue()构造一个空的优先级队列
priority_queue(first, last)构造一个优先级队列,包含范围为[first, last)的元素
empty()检测优先级队列是否为空,是返回true,否则返回false
top()返回优先级队列中最大(最小)元素,即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int main()
{
	priority_queue<int> pq;//这里默认是大堆
	pq.push(3);
	pq.push(2);
	pq.push(6);
	pq.push(9);
	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
	cout << endl;

	priority_queue<int, vector<int>, greater<int>> pq2;//这里传入一个类型greater<int>(马上就讲了)
	pq2.push(3);
	pq2.push(2);
	pq2.push(6);
	pq2.push(9);
	while (!pq2.empty())
	{
		cout << pq2.top() << " ";
		pq2.pop();
	}
	cout << endl;
	return 0;
}

image-20240130194228894

1.3进一步补全介绍

优先队列(priority_queue)是一个特殊的队列,它根据元素的优先级进行排序,而不是按照它们被插入的顺序。在C++中,优先队列通常使用堆(heap)数据结构来实现,这使得它能够在==O( l o g n logn logn)的时间复杂度内对元素进行插入和删除操作,并能够以O(1)的时间复杂度获取队列中的最大(或最小)==元素。

以下是优先队列(priority_queue)的一些重要特性和接口:

  1. 构造函数
    • priority_queue<Type, Container, Compare>:创建一个优先队列对象,其中Type是元素类型,Container是底层容器类型(默认为vector),Compare是元素比较的函数对象类型(默认为std::less,用于最大堆)。
    • priority_queue(first, last):使用范围为[first, last)的迭代器构造一个优先队列。
  2. 默认行为
    • 默认情况下,优先队列是最大堆,即最大元素位于堆顶。可以通过自定义比较函数对象来改变这一行为,从而创建最小堆或者基于自定义的优先级规则进行排序。
  3. 底层实现
    • 在C++中,优先队列通常使用vector或deque作为底层容器,并通过堆算法来维护元素的顺序。

2.仿函数/函数对象讲解

函数对象(Functor)也称为仿函数(Function Object),是C++中的一种重要概念,它是一个行为类似函数的对象,可以被当作函数来调用。在C++中,函数对象可以以类的形式实现(其实是个类)重载operator()运算符,从而可以像函数一样被调用

函数对象可以提供比普通函数更多的灵活性和功能,它可以保存状态、具有成员变量、可以在构造函数中接受参数等。函数对象通常用于STL中的算法、容器和适配器中,它们可以作为参数传递给算法,用于自定义排序、查找、比较等操作。

namespace FunctionObject
{
	template<class T>
	class less
	{
	public:
		bool operator()(const T& a, const T& b)
		{
			return a < b;
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& a, const T& b)
		{
			return a > b;
		}
	};
}

void test1()
{
	int a = 1;
	int b = 10;
	FunctionObject::greater<int> big;//定义一个对象
	cout << big(a, b) << endl;//只看big(a, b) 跟函数调用长得一样
}

int main()
{
	test1();
	return 0;
}

image-20240130195912118


3.模拟priority_queue

文件规划和一览

在这里插入图片描述

priority_queue.h:用来实现queue

test.cpp:进行测试

3.1模拟priority_queue(priority_queue.h)

#pragma once

namespace MyPriority_queue
{
	template<class T>
	class less
	{
	public:
		bool operator()(const T& a, const T& b)
		{
			return a < b;
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& a, const T& b)
		{
			return a > b;
		}
	};

	template<class T, class Container = vector<T>, class Compare = less<T>>//默认是大堆
	class priority_queue
	{
	public:

		void adjust_up(int child)
		{
			Compare com;
			int father = (child - 1) / 2;//得到父节点的索引
			while (child > 0)//再怎么向上也只能到0
			{
				if (com(_con[father], _con[child]))
				{
					swap(_con[father], _con[child]);
					child=father;
					father= (child - 1) / 2;//更新两个节点
				}
				else
				{
					break;
				}
			}
		}

		void adjust_down(int father)
		{
			Compare com;
			int child = father * 2 + 1;//假设左孩子较大
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))//右孩子存在且比左孩子大
				{
					child++;
				}

				if(com(_con[father], _con[child]))
				{
					swap(_con[father], _con[child]);
					father=child;
					child = father * 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);
		}

		const T& top()
		{
			return _con[0];
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}

	private:
		Container _con;
	};
}

3.2测试(test.cpp)

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#include"priority_queue.h"

int main()
{
	MyPriority_queue::priority_queue<int> pq;//这里默认是大堆
	pq.push(3);
	pq.push(2);
	pq.push(6);
	pq.push(9);
	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
	cout << endl;

	priority_queue<int, vector<int>, MyPriority_queue::greater<int>> pq2;
	pq2.push(2);
	pq2.push(6);
	pq2.push(9);
	while (!pq2.empty())
	{
		cout << pq2.top() << " ";
		pq2.pop();
	}
	cout << endl;
	return 0;
}

image-20240130210120238


后天开学,今天也是才到学校,正月十五就一人在宿舍过了😭😭😭
到此为止,容器的部分我们大都讲完啦!!!大家敬请期待接下来的知识分享吧!!!

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

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

相关文章

k8s-helm部署应用 19

Helm部署nfs-client-provisioner&#xff08;存储类&#xff09;&#xff1a; 预先配置好外部的NFS服务器 部署 Helm部署nginx-ingress应用&#xff1a; 添加下载ingress 拉取 解开并修改 部署 测试 回收 helm部署metrics-server&#xff1a; 清除之前的metrics部署 下载…

QT问题 打开Qt Creator发现没有菜单栏

之前不知道按了什么快捷键,当我再次打开Qt Creator时发现菜单栏消失啦 找了许多原因发现:安装有道词典的快捷键Ctrl Alt m 与Qt Creator里的快捷键冲突导致菜单栏被莫名其妙的隐藏 解决方法: 1找到有道词典快捷键 2再次按快捷键 Ctrl Alt m就可以重新显示菜单栏

Linux系统——nginx服务补充

目录 一、Nginx调优补充 1.验证模块——登录 1.1htpasswd 1.1.1htpasswd -c——交互式 1.1.2htpasswd -b——免交互式 2.自定义错误页面 2.1设置错误页面——想让客户端看到的页面 2.2自定义错误码 3.日志位置存放&#xff08;可以自定义存放位置&#xff09; 4.检测…

零基础手把手教你创建微信小程序(二)·创建第一个微信小程序以及了解小程序代码的构成

零基础手把手教你创建微信小程序&#xff08;一&#xff09;微信小程序开发账号的注册以及开发者工具的安装和使用-CSDN博客 目录 ​编辑 1. 创建微信小程序 1.1 基本信息 1.2 在模拟器上查看项目效果 1.3 在真机上预览项目效果 1.4 主界面的5个组成部分 1.4.1 菜单…

华为HCIP Datacom H12-831 卷23

单选题 1、某园区部署IS-IS实现网络互通&#xff0c;在所有IS-IS路由器的进程中配置命令flash-flood 6 max-timer-interval 100 Leve1-2&#xff0c;则以下关于该场景的描述,正确的是哪—项? A、若某IS-IS路由器LSDB内更新的LSP数量为5,则在100毫秒内且路由计算完成前&#…

对象怎样才会进入老年代?

JVM 对象内存分配&#xff1a;空间担保机制案例演示&#xff1a;对象分配过程01-大对象直接进入老年代02-对象内存分配的过程&#xff1a;案例演示&#xff1a;内存担保机制 对象内存分配&#xff1a; 新生代&#xff1a;新对象大多数都默认进入新生代的Eden区进入老年代的条件…

盲盒小程序开发:线上盲盒带来的发展

盲盒在我国的发展一直处于稳步上升阶段&#xff0c;盲盒的未知性和刺激性为消费者带来了全新的娱乐消费模式。并且盲盒具有的收藏价值也吸引着消费者进行复购&#xff0c;使消费者欲罢不能。在盲盒的不断创新发展&#xff0c;形成了一套可持续发展的商业模式&#xff0c;具有较…

企业微信怎么变更企业名称?

企业微信变更主体有什么作用&#xff1f;现在很多公司都用企业微信来加客户&#xff0c;有时候辛辛苦苦积累了很多客户&#xff0c;但是公司却因为各种各样的原因需要注销&#xff0c;那么就需要通过企业微信变更主体的方法&#xff0c;把企业微信绑定的公司更改为最新的。企业…

并发编程(4)共享模型之无锁

6 共享模型之无锁 本章内容 CAS 与 volatile原子整数原子引用原子累加器Unsafe 6.1 问题提出 有如下需求&#xff0c;保证 account.withdraw 取款方法的线程安全 import java.util.ArrayList; import java.util.List;interface Account {// 获取余额Integer getBalance();…

spring框架介绍

spring 1.优点 1&#xff09;针对接口编程&#xff0c;解耦合 2&#xff09;aop&#xff1a;变向切面编程&#xff0c;动态增加功能 3&#xff09;方便集成框架&#xff0c;mybatis,hibernate,strust等 4&#xff09;降低j2ee接口的使用难度 2.spring是干什么的 管理bean及bean…

私域运营-需要认清的事实

一、私域不能单纯依靠微信渠道 误区&#xff1a;很多企业仍停留在如何让用户在微信去分享裂变&#xff0c;然后带动新用户的阶段。 私域的核心在于“开源节流”&#xff0c;就是如何通过更多渠道获取更多客户&#xff0c;并且避免客户的批量流失。 私域讲究的是如何从公域的“…

【IDEA】安装Jrebel实现热部署

前言 devtool虽然也可以实现热部署 但是新增完方法和修改完参数后 热部署不生效 需要重启 而Jrebel却不用 功能也比devtool强大 但是收费 这里教大家怎么使用 插件下载 激活Jrebel

Qiskit模块介绍

中文版reference Terra Qiskit最基本的模块&#xff0c;相当于Qiskit包的前端&#xff0c;包含了Quantum Circuits、Transpiler等,包括了定义、编译量子电路&#xff0c;以及在模拟器或是量子设 备上运行电路的工具。 Aer 相当于Qiskit包的后端&#xff0c;高性能模拟器&…

DC与DCT DCG的区别

先进工艺不再wire load model进行静态时序分析&#xff0c;否则综合结果与后端物理电路差距很大&#xff0c;因此DC综合工具也进行了多次迭代&#xff0c;DC工具有两种模式&#xff0c;包括wire load mode和Topographical Mode&#xff0c;也就是对应的DC Expert和DC Ultra。 …

牛客网 HJ10 字符个数统计

思路&#xff1a; 我们创建两个数组&#xff0c;一个数组接受输入的字符&#xff0c;另一个数组用来统计字符种数 同时将该字符作为下标传给另一个数组&#xff0c;如果另一个数组的这个下标对应的值为0&#xff0c;说明该字符没有被统计过&#xff0c;计数器加1&#xff0c;…

vue+node.js美食分享推荐管理系统 io551

&#xff0c;本系统采用了 MySQL数据库的架构&#xff0c;在开始这项工作前&#xff0c;首先要设计好要用到的数据库表。该系统的使用者有二类&#xff1a;管理员和用户&#xff0c;主要功能包括个人信息修改&#xff0c;用户、美食类型、美食信息、订单信息、美食分享、课程大…

洛谷P8627 [蓝桥杯 2015 省 A] 饮料换购

#先看题目 题目描述 乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊 C 型饮料&#xff0c;凭 3 个瓶盖可以再换一瓶 C 型饮料&#xff0c;并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下&#xff0c;如果小明不浪费瓶盖&#xff0c;尽量地参加活动&#xff0c;那…

AD24-PCB的DRC电气性能检查

1、 2、如果报错器件选中&#xff0c;不能跳转时&#xff0c;按下图设置 3、开始出现以下提示时处理 4、到后期&#xff0c;错误改得差不多的时候&#xff1b;出现以下的处理步骤 ①将顶层和底层铜皮选中&#xff0c;移动200mm ②执行以下操作 ③将铜皮在移动回来&#xff0c;进…

使用向量数据库pinecone构建应用01:相似语义检索 Semantic Search

Building Applications with Vector Databases 下面是DeepLearning.AI上面这门课的学习笔记&#xff1a;https://www.deeplearning.ai/short-courses/building-applications-vector-databases/ Learn to create six exciting applications of vector databases and implement…

css3盒子

盒子模型 一.看透网页布局本质二.认识盒子三.盒子的边框&#xff08;border&#xff09;1.概念2.简写及分开写法3.合并问题&#xff08;会相加&#xff09;4.边框会影响盒子实际大小 四.盒子的内边距&#xff08;padding&#xff09;1.概念2.简写3.内边距会影响盒子实际大小4.特…