C++——STL容器【priority_queue】模拟实现

news2024/11/24 15:01:00

在这里插入图片描述

本章代码:优先级队列模拟实现、priority_queue文档

文章目录

  • 🐈1. priority_queue介绍
  • 🦄2. priority_queue模拟实现
    • 🐧2.1 构造函数
    • 🐧2.2 建堆
      • 向下调整
      • 向上调整
    • 🐧2.3 仿函数
    • 🐧2.4 push & pop操作
    • 🐧2.5 top & empty & size

🐈1. priority_queue介绍

priority_queue在STL里面是队列的一种,叫做优先级队列,它的底层是基于实现的,默认的是大堆。

它的使用方法与queue类似,可理解为priority_queue是一个可以排序的队列

🦄2. priority_queue模拟实现

先查看文档,看看支持了哪些接口:

image-20230806212745863

🐧2.1 构造函数

priority_queue采用的vector作为容器适配器,那默认构造直接调用vector的就行,然后构造还支持迭代器初始化:

priority_queue()
{}

template<class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
	while (first != last)
	{
		_con.push_back(*first);
		++first;
		
		//建堆
		for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
		{
			AdjustDown(i);
		}
	}
}

🐧2.2 建堆

向下调整的时间复杂度是O(N),向上调整的时间复杂度是O(N*logN),所以采用向下调整建堆

详细讲解可查看:数据结构——二叉树(堆、堆排序、二叉树链式结构)

向下调整

//向下调整 默认大堆
void AdjustDown(int parent)
{
	int child = parent * 2 + 1;
	while (child < _con.size())
	{
		if (child + 1 < _con.size() && _con[child + 1] > _con[child])
		{
			child = child + 1;
		}
		if (_con[child] > _con[parent])
		{
			std::swap(_con[child], _con[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

向上调整

//向上调整
void AdjustUp(int child)
{
	int parent = (child - 1) / 2;

	while (child > 0)
	{
		if (_con[child] > _con[parent])
		{
			std::swap(_con[child], _con[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

🐧2.3 仿函数

STL的priority_queue默认是大堆,如果想要指定小堆,则需要在参数列表里面指定参数

std::priority_queue<int> maxHeap;  // 默认:大堆
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;	//小堆

这里我们要实现,就要用到仿函数

仿函数是一个,它重载了函数调用运算符operator(),这使得这个类就可以想函数一样被调用

在这里我们就重载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;
	}

};

priority_queue不指定的情况下,默认是大堆,指定模板时将Less设为缺省参数即可

template<class T, class Container = vector<T>, class Compare = Less<T>>
class priority_queue

有了仿函数,我们的向下调整和向上调整在选择建大堆或者小堆的时候,调用这个仿函数即可:

//向下调整 默认大堆
void AdjustDown(int parent)
{
	Compare com;
	int child = parent * 2 + 1;
	while (child < _con.size())
	{
		//if (child + 1 < _con.size() && _con[child + 1] > _con[child])
		if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
		{
			child = child + 1;
		}
		//if (_con[child] > _con[parent])
		if (com(_con[parent], _con[child]))
		{
			std::swap(_con[child], _con[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//向上调整
void AdjustUp(int child)
{
	Compare com;
	int parent = (child - 1) / 2;

	while (child > 0)
	{
		//if (_con[child] > _con[parent])
		if (com(_con[parent], _con[child]))
		{
			std::swap(_con[child], _con[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

🐧2.4 push & pop操作

  • 插入操作即在队尾增加一个元素,然后向上调整,保证这还是一个堆

  • 删除操作还是模拟堆的操作,将首元素和最后一个元素交换,然后删除队尾元素

    这样保证了即使删除之后,下面的还是一个堆,接下来向下调整即可

void pop()
{
	std::swap(_con[0], _con[_con.size() - 1]);
	_con.pop_back();
	AdjustDown(0);
}
void push(const T& x)
{
	_con.push_back(x);
	AdjustUp(_con.size() - 1);
}

🐧2.5 top & empty & size

emptysize直接调用vector的接口即可;top查看队头元素,返回队头元素即可

const T& top() const
{
	return _con[0];
}
bool empty() const
{
	return _con.empty();
}
size_t size()
{
	return _con.size();
}

那本期的分享就到这咯,我们下期再见,如果还有下期的话

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

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

相关文章

通向架构师的道路之漫谈使用ThreadLocal改进你的层次的划分

一、什么是ThreadLocal 早在JDK 1.2的版本中就提供java.lang.ThreadLocal&#xff0c;ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义&#xff0c;想当然地认为是一个“本地线…

MapTR论文笔记

MAPTR: STRUCTURED MODELING AND LEARNING FOR ONLINE VECTORIZED HD MAP CONSTRUCTION 目的 传统高精地图 通过一些离线的基于 SLAM 的方法生成&#xff0c;需要复杂的流程以及高昂的维护费用。基于 bev 分割的建图方法&#xff0c;缺少向量化 实例级的信息&#xff0c;比如…

SPM(Swift Package Manager)开发及常见事项

SPM怎么使用的不再赘述&#xff0c;其优点是Cocoapods这样的远古产物难以望其项背的&#xff0c;而且最重要的是可二进制化、对xcproj项目无侵入&#xff0c;除了网络之外简直就是为团队开发的项目库依赖最好的管理工具&#xff0c;是时候抛弃繁杂低下的cocoapods了。 一&…

如何使用 ChatGPT 规划家居装修

你正在计划家庭装修项目&#xff0c;但不确定从哪里开始&#xff1f;ChatGPT 随时为你提供帮助。从集思广益的设计理念到估算成本&#xff0c;ChatGPT 可以简化你的家居装修规划流程。在本文中&#xff0c;我们将讨论如何使用 ChatGPT 有效地规划家居装修&#xff0c;以便你的项…

vue diff 前后缀+最长递增子序列算法

文章目录 查找相同前后缀通过前后缀位置信息新增节点通过前后缀位置信息删除节点 中间部份 diff判断节点是否需要移动删除节点删除未查找到的节点删除多余节点 移动和新增节点最长递增子序列 求解最长递增子序列位置信息 查找相同前后缀 如上图所示&#xff0c;新旧 children 拥…

SCT82A30DHKR_5.5V-100V Vin同步降压控制器

SCT82A30是一款100V电压模式控制同步降压控制器&#xff0c;具有线路前馈。40ns受控高压侧MOSFET的最小导通时间支持高转换比&#xff0c;实现从48V输入到低压轨的直接降压转换&#xff0c;降低了系统复杂性和解决方案成本。如果需要&#xff0c;在低至6V的输入电压下降期间&am…

Photoshop 2023 25.0beta「Mac」

Photoshop 2023是一款专业图像处理软件&#xff0c;它主要用于图像编辑、合成和设计等方面。 Photoshop beta创新式填充的功能特色包括&#xff1a; 自动识别和删除对象&#xff1a;该功能可以自动识别图像中的对象&#xff0c;并用周围的图像填充空白部分&#xff0c;使图像看…

window系统下 tinymce富文本编辑器在搜狗输入法下placeholder不消失现象

window 搜狗输入法下编辑器占位符和内容重叠问题 这种情况是&#xff0c;tinymce插件库存在一些兼容BUG&#xff0c;需要我们自行手写样式或者js替换掉placeholder&#xff0c;代码如下&#xff1a; // 获取富文本框的内容const handleChange (editorContent) > {// cons…

C++11 新特性 ---- final 和 override

一、final C中增加了final关键字&#xff0c;作用如下&#xff1a; ① 限制某个类不能被继承② 或者某个虚函数不能被重写 ① 限制某个类不能被继承 // ① 限制某个类不能被继承,也就是说这个类不能有派生类 class Base{ public:virtual void print() {cout<<"Ba…

电商数据获取:网络爬虫还是付费数据接口?

随着电商行业的迅速发展&#xff0c;对电商数据的需求也越来越大。在获取电商数据时&#xff0c;常常面临一个选择&#xff1a;是自己编写网络爬虫进行数据爬取&#xff0c;还是使用现有的付费数据接口呢&#xff1f;本文将从成本、可靠性、数据质量等多个角度进行分析&#xf…

【css】组合器

组合器是解释选择器之间关系的某种机制。在简单选择器器之间&#xff0c;可以包含一个组合器&#xff0c;从而实现简单选择器难以达到的效果。 CSS 中有四种组合器&#xff1a; 后代选择器 (空格)&#xff1a;匹配属于指定元素后代的所有元素&#xff0c;示例&#xff1a;div …

element-ui表格数据为空,图片占位提示

当表格的绑定数据为空时常需要显示暂无数据等字样&#xff0c;这时候就用到了empty-text <el-table:data"tableData"stripeborderempty-text"暂无数据"> 但&#xff0c;当数据为空&#xff0c;想用图片展示呢&#xff0c;如下图 方法一&#xff1a…

java.lang.UnsupportedClassVersionError TestCase

JavaFramework-JDK6.jar 放到JDK17运行没有问题 JavaFramework源码放到JDK17环境下编译出来的JavaFramework-JDK17.jar JavaFramework-JDK17.jar 放到JDK17运行没有问题 JavaFramework-JDK17.jar 放到JDK8运行没有问题&#xff0c;这个好像不对啊&#xff0c;可能之前编译设置…

day39反转字符串总结

反转字符串原理其实就是交换位置&#xff0c;以中间为分隔点&#xff1b; 基本套路&#xff1a;遍历前一般字符&#xff0c;互换位置&#xff1b; for循环模板 void reverseString(char* s, int sSize){char temp;for (int i 0, j sSize - 1; i < sSize/2; i, j--) {temp…

【无公网IP】本地电脑搭建个人博客网站(并发布公网访问 )和web服务器

【无公网IP】本地电脑搭建个人博客网站&#xff08;并发布公网访问 &#xff09;和web服务器 文章目录 【无公网IP】本地电脑搭建个人博客网站&#xff08;并发布公网访问 &#xff09;和web服务器前言1. 安装套件软件2. 创建网页运行环境 指定网页输出的端口号3. 让WordPress在…

【Rust】Rust学习第三章常见编程概念

包含第一、二章 文档&#xff1a;Rust 程序设计语言 - Rust 程序设计语言 简体中文版 (bootcss.com) 墙裂推荐这个文档 第一章入门 入门指南 - Rust 程序设计语言 简体中文版 第二章猜猜看游戏 猜猜看游戏教程 - Rust 程序设计语言 简体中文版 (bootcss.com) // 导入库 us…

Stable Diffusion 硬核生存指南:WebUI 中的 GFPGAN

本篇文章聊聊 Stable Diffusion WebUI 中的核心组件&#xff0c;强壮的人脸图像面部画面修复模型 GFPGAN 相关的事情。 写在前面 本篇文章的主角是开源项目 TencentARC/GFPGAN&#xff0c;和上一篇文章《Stable Diffusion 硬核生存指南&#xff1a;WebUI 中的 CodeFormer》提…

H263压缩码流如何分解为一个一个单元并查询到其宽高?

H263码流尺寸规格有限&#xff0c;只有以下几种&#xff1a; H263码流有四个分层&#xff1a; 1、图像层 2、块组 3、宏块 4、块 下面分别介绍&#xff1a; 具体介绍如下&#xff0c;5.1.3中红色框选部分就是压缩码流的宽高指示&#xff1a; 图像层 上面就是H263的图像层&am…

QT开发学习相关笔记

QT中配置文件读取 QT中使用的config文件为&#xff1a;xxx.ini文件,基本格式如下&#xff1a; 使用 QSetting&#xff08;QT自带类&#xff09;中的相关接口实现设置配置文件数据&#xff0c;或者读取数据。 读取配置文件路径设置如下&#xff0c;其中 iniPath为设置路径 ne…

word2003脚注问题

问题分析&#xff1a; 在题目上插入脚注的时候&#xff0c;脚注放在文件结尾&#xff0c;然后正文拆开了&#xff0c;不能续前节 解决办法&#xff1a; word2003中&#xff0c;工具->选项->兼容性