C++:模拟priority_queue

news2024/10/24 16:07:37

目录

priority_queue的介绍

概念

特点

priority_queue的使用

基本操作

演示代码

​编辑

priority_queue的模拟实现

仿函数

向上调整和向下调整

模拟实现的代码


priority_queue的介绍

概念

在C++标准库中,priority_queue是一个基于优先级堆的容器适配器。它的底层容器是vector,将其封装成堆来管理元素,确保元素按照特定的优先级顺序排列。

默认情况下,priority_queue是大堆,因为其的比较函数是std::less,如果想要建立小堆,则使用std::greater比较函数,这个比较函数其实是仿函数,接下来会提及。

特点

1.自动排序

元素根据优先级自动排序,最高优先级的元素总是在队列的前端。

2.只访问前端元素

只能访问队列的前端元素,即最高优先级的元素。

3.底层容器

使用vector作为底层容器来存储元素,但用户不能直接访问这个容器。

4.元素比较

priority_queue需要一个比较函数或函数对象来确定元素的优先级顺序默认情况下使用std:less,即最大值优先。

priority_queue的使用

基本操作

  • empty():检查队列是否为空。
  • size():返回队列中的元素数量。
  • top()访问队列前端的元素(不删除)。
  • pop()移除队列前端的元素。
  • push():向队列添加新元素。

演示代码

int main()
{
	std::priority_queue<int, vector<int>, less<int>> pq;
	pq.push(2);
	pq.push(1);
	pq.push(4);
	pq.push(5);
	pq.push(3);

	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
	cout << endl;

	return 0;
}

priority_queue的模拟实现

仿函数

要想实现priority_queue,我们首先需要了解仿函数。

在 C++ 中,仿函数(Functor)是一种重载了函数调用操作符 operator() 的类或结构体。仿函数可以像函数一样被调用,但它们实际上是对象,因此可以拥有成员变和成员函数。

仿函数是函数对象(function object)的一种,它们通常用于需要函数指针或函数引用的地方,尤其是当需要传递具有特定行为的对象时

仿函数的一些关键特性:

  1. 重载 operator()

    仿函数必须重载函数调用操作符 operator(),使其能够像函数一样被调用。
  2. 状态存储

    仿函数可以拥有自己的数据成员,这些成员存储了仿函数的状态。
  3. 行为封装

    仿函数可以封装特定的行为,这些行为可以通过其 operator() 实现。
  4. 灵活性

    仿函数提供了比普通函数更多的灵活性,因为它们可以存储状态,并且可以被重载。
  5. STL 兼容性

    仿函数与 STL 容器和算法兼容,可以作为算法的参数传递。

仿函数的简单示例

上面我们提到std::less就是一个仿函数,我们就来模拟实现下。

template<class T>
class Less
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x < y;
	}
};

向上调整和向下调整

我们知道priority_queue其实是堆,既然是堆那就需要实现向上调整和向下调整算法。

void AdjustDown(int parent)
{
	int child = 2 * parent + 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 = 2 * parent + 1;
		}
		else
		{
			break;
		}
	}
}

void AdjustUp(int child)
{
	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;
		}
	}
}

模拟实现的代码

template<class T>
class Less
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x < y;
	}
};

template<class T, class Container = vector<T>, class Compare = Less<T>>
class priority_queue
{
public:
	void AdjustDown(int parent)
	{
		int child = 2 * parent + 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 = 2 * parent + 1;
			}
			else
			{
				break;
			}
		}
	}

	void AdjustUp(int child)
	{
		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 pop()
	{
		swap(_con[0], _con[_con.size() - 1]);
		_con.pop_back();
		AdjustDown(0);
	}

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

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

	int size() const
	{
		return _con.size();
	}


private:
	Container _con;
	Compare _com;
};

拜拜,下期再见😏

摸鱼ing😴✨🎞

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

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

相关文章

设计感十足的喇叭裤来咯,亲子款get~

微喇叭的设计&#xff0c;时尚感爆棚&#xff0c;瞬间让宝贝成为冬日里的小潮人。而且这种设计非常显瘦&#xff0c;能够很好地修饰宝贝的腿型&#xff0c;穿上秒变大长腿。表面磨毛质感&#xff0c;摸起来舒软绒顺&#xff0c;温柔气质&#xff0c;下脚隐形拉链&#xff0c;拉…

如何通过 Nginx 只允许 www 域名访问并禁止裸域名访问

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

learn C++ NO.23——map、set的模拟实现

STL库的实现方式 map和set的底层用的红黑树是一样的吗&#xff1f;从容器特点的角度出发&#xff0c;这里个容器的底层应该分别用key搜索模型的红黑树和key value 搜索模型的红黑树。但是&#xff0c;从库的设计角度出发&#xff0c;这两者用同一份红黑树代码更好。而STL就是用…

第十五章 RabbitMQ延迟消息之延迟插件

目录 一、引言 二、延迟插件安装 2.1. 下载插件 2.2. 安装插件 2.3. 确认插件是否生效 三、核心代码 四、运行效果 五、总结 一、引言 上一章我们讲到通过死信队列组合消息过期时间来实现延迟消息&#xff0c;但相对而言这并不是比较好的方式。它的代码实现相对来说比…

Java->排序

目录 一、排序 1.概念 2.常见的排序算法 二、常见排序算法的实现 1.插入排序 1.1直接插入排序 1.2希尔排序(缩小增量法) 1.3直接插入排序和希尔排序的耗时比较 2.选择排序 2.1直接选择排序 2.2堆排序 2.3直接选择排序与堆排序的耗时比较 3.交换排序 3.1冒泡排序…

你知道C++多少——继承

&#x1f308;个人主页&#xff1a;小新_- &#x1f388;个人座右铭&#xff1a;“成功者不是从不失败的人&#xff0c;而是从不放弃的人&#xff01;”&#x1f388; &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f3c6;所属专栏&#xff1…

蓝桥杯模块三:蜂鸣器和继电器的基本控制

模块训练题目&#xff1a; 一、蜂鸣器电路图 1.电路图 2.电路分析 138译码器控制Y5,Y5控制Y5C&#xff0c;Y5C低电平控制芯片开启P0口控制ULN2003继而控制蜂鸣器端口和继电器端口 二、程序代码 1.138译码器控制端口函数 建立初始化函数选择锁存器 2.实现题目功能 在LED代…

24-10-13-读书笔记(二十五)-《一只特立独行的猪》([中] 王小波)用一生来学习艺术

文章目录 《一只特立独行的猪》&#xff08;[中] 王小波&#xff09;目录阅读笔记记录总结 《一只特立独行的猪》&#xff08;[中] 王小波&#xff09; 十月第五篇&#xff0c;放慢脚步&#xff0c;秋季快要过去了&#xff0c;要步入冬季了&#xff0c;心中也是有些跌宕起伏&am…

Guitar Pro怎么制作伴奏谱,吉他谱制作软件guitar pro教程

在诸多教学吉他谱制作软件中Guitar Pro是一款非常优秀的软件&#xff0c;它是专为吉他和其他弦乐器设计&#xff0c;且能提供乐谱编辑、音轨录制和播放、和弦与音阶库等功能的强大软件。Guitar Pro不仅具有强大的乐谱编辑功能&#xff0c;其用户界面也易于上手&#xff0c;更支…

ThingsBoard规则链节点:Script节点详解

引言 脚本节点简介 用法 含义 应用场景 实际项目运用示例 智能楼宇管理系统 工业自动化生产线 结论 引言 ThingsBoard是一个功能强大的物联网平台&#xff0c;它支持设备管理、数据收集与处理以及实时监控。其核心组件之一是规则引擎&#xff0c;允许用户定义复杂的业务…

vue特效,一片动态星空

vue实现漂亮星空&#xff0c;超级简单 1.创建vue项目&#xff1a; vue create demo 2.注册vuecli : npm i element-ui -S 3.加载依赖 &#xff1a;npm i 4.运行项目 :npm run serve <!DOCTYPE html> <html lang"en"> <head><…

JavaWeb 19 AJAX

"我就是希望你好&#xff0c;就像很多人希望我好一样&#xff0c;特别简单&#xff0c;特别真挚。也不为了什么&#xff0c;就是希望你好" —— 24.10.13 一、什么是AJAX AJAX Asynchronous JavaScript and XML(异步的JavaScript和XML) AJAX不是新的编程语言&…

仿新版QQ的聊天小软件

仿新版QQ的聊天小软件 文章说明核心源码效果展示源码下载 文章说明 新开一个聊天组件的项目的想法主要来源于想学习一下消息队列的使用&#xff0c;后来在书写界面和一些功能模块时&#xff0c;又想到可以抽离出来&#xff0c;分别写几篇文章&#xff0c;主要介绍扫码登陆、消息…

MQ快速入门【详细】个人笔记 讲解通俗易懂

1.同步通讯和异步通讯 同步通讯&#xff1a;如果举个例子来说&#xff0c;同步通讯就像是两个人在打电话&#xff0c;一方说的话&#xff0c;能够立马传给另一方&#xff0c;消息的时效性非常高&#xff0c;但是相对的&#xff0c;只能是给一个人通讯&#xff0c;如果这个时候&…

React (三) 创建安装脚手架,类组件与函数式组件;生命周期;父子通信props;插槽;非父子通信Context

文章目录 一、脚手架的创建与安装1. 认识脚手架2. 安装脚手架3. 创建react项目4. 项目结构 二、从0编写三、组件化开发1. 什么是组件化开发2. 类组件3. render函数4. 函数式组件 四、生命周期1. 挂载Mount2. 更新Update3. 卸载Unmount4. 不常用的生命周期 五、父子组件通信1. 父…

数据结构之队列(python)

华子目录 1.队列存储结构1.1队列基本介绍1.2队列的实现方式 2.顺序队列2.1顺序队列的介绍2.2顺序队列的简单实现2.3代码实现 3.链式队列和基本操作3.1链式队列数据入队3.2链式队列数据出队3.3队列的链式表示和实现 1.队列存储结构 1.1队列基本介绍 队列的两端都"开口&qu…

springcloud之服务集群注册与发现 Eureka

前言 1&#xff1a;对于能提供完整领域服务接口功能的RPC而言&#xff0c;例如&#xff1b;gRPC、Thrift、Dubbo等&#xff0c;服务的注册与发现都是核心功能中非常重要的一环&#xff0c;使得微服务得到统一管理。 2&#xff1a;在分布式领域中有个著名的CAP理论&#xff1b;…

Vue3 + Element plus 实现切换el-radio前二次确认

Vue3 Element plus 实现切换el-radio前二次确认 场景&#xff1a;点击切换el-radio之前判断当前内容是否有改变&#xff0c;如有改变弹窗提示切换el-radio将销毁操作&#xff0c;弹窗二次确认是否切换 问题&#xff1a; el-radio 没有提供类似于beforeUpdate这样的钩子去处理这…

探索极简计算的新边界:从Uxn虚拟机看未来编程生态

越来越多的开发者追求复杂度和功能性的极致,然而,有一个小众的编程社区选择了截然不同的道路——极简主义。Uxn虚拟机便是这一思潮的代表之一。它通过简洁的指令集和有限的硬件资源模拟,试图打造一种可以在多种设备上运行的便携性编程环境。 与主流的重型操作系统和复杂…

HTB:Legacy[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are open on Legacy? 2.What is the 2008 CVE ID for a vulnerability in SMB that allows for remote code execution? 3.What is the name of the Metasploit module that exploits CVE-2008-4250? 4.When expl…