优先级队列、仿函数和反向迭代器

news2024/11/19 16:45:02

image-20230112094358779

文章目录

  • 优先级队列
    • priority_queue的模拟实现
      • 框架
      • 无参的构造(默认构造)
      • 迭代器区间构造
      • 向上调整
      • 向下调整
      • 插入
      • 删除
      • 取堆顶的数据
      • 求数据个数
      • 验满
    • 初识仿函数
      • 模拟实现
        • 仿函数更改后的向上调整
        • 仿函数更改后的向下调整
  • 反向迭代器
        • 具体实现

优先级队列

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

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

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

4.标准容器类vector和deque满足这些需求。默认情况下,如果没有特定的priority_queue类实例化指定容器类,则使用vector。

5.实际数据类型是数组

priority_queue的模拟实现

默认情况下,priority_queue是大堆

框架

template<class T,class Container = vector<T>>
    class class Priority_Queue
	{
	public:
        //实现
        ......
    private:
    Container _con;

无参的构造(默认构造)

Priority_Queue()//会调用适配器的默认构造
		{}

迭代器区间构造

		template<class InputIterator>
		Priority_Queue(InputIterator first, InputIterator last)
			:_con(first,last)
		{
			//向下建堆
			for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
			{
				adjust_down(i);//向下调整
			}
		}

向上调整

void adjust_up(size_t child)
		{
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				if (_con[child] > _con[parent])//建大堆
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

image-20230111181717938

向下调整

		void adjust_down(size_t parent)
		{
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && _con[child + 1] > _con[child])//大堆
				{
					child++;
				}
				if (_con[child]> _con[parent])//大堆
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
					
				}
				else
				{
					break;
				}
			}
		}

image-20230111181753777

插入

		void push(const T& val)
		{
			_con.push_back(val);
			adjust_up(_con.size() - 1);//把新插入的儿子的下标传过去,然后向上调整
		}

删除

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);//头删-先和最后的儿子交换,然后再尾删
			_con.pop_back();
			adjust_down(0);//向下调整
		 }

取堆顶的数据

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

求数据个数

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

验满

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

初识仿函数

通过查阅优先级队列的大堆小堆的实现,大于和小于的地方使用的是仿函数里面的比较。仿函数引用的头文件是 #include< functional >

模拟实现

template<class T>
	class less//大根堆
	{
	public:
		bool operator()(const T& x,const T& y)const
		{
			return x < y;//后一个是否小于前一个
		}
	};
	template<class T>
	class greater//小根堆
	{
	public:
		bool operator()(const T& x, const T& y)const
		{
			return x > y;//后一个是否大于前一个
		}
	};

1.这里的仿函数的大于小于的比较由仿函数的实现决定,而底层不会暴露出来,更安全。

2.仿函数针对的是泛型,用法更广泛。比如比较的是内嵌类型,那么天然的>或者<可能可以满足,而对应自定义类型的比较,就需要自己去实现然后封装起来。

比如用在冒泡排序,以往的冒泡排序的实现,具体的升序和降序由模拟实现中的>或<号决定,而这符号等于暴露了底层实现。那么这里可以通过仿函数隐藏起来,不保留底层实现。

image-20230111203406289

仿函数更改后的向上调整

		void adjust_up(size_t child)
		{
			Compare Com;
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[parent]<_con[child])//建大堆
				  if(Com(_con[parent],_con[child]))
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

仿函数更改后的向下调整

void adjust_down(size_t parent)
		{
			Compare Com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//if (child + 1 < _con.size() && _con[child] < _con[child+1])//大堆
				if(child+1<_con.size()&&Com(_con[child],_con[child+1]))
				{
					child++;
				}
				//if (_con[parent]> _con[child])//大堆
				if(Com(_con[parent],_con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
					
				}
				else
				{
					break;
				}
			}
		}

image-20230111204637666

反向迭代器

反向迭代器和迭代器的起始是对称的,但反向迭代器在解引用的时候有所不同,取数据时先反向迭代器–再解引用。

image-20230112093236573

image-20230112093248833

具体实现

template<class Iterator, class Ref, class Ptr>
class ReverseIterator
{
	typedef ReverseIterator<Iterator, Ref, Ptr> Self;

public:
	ReverseIterator(Iterator it)
		:_it(it)
	{}

	Ref operator*()
	{
		Iterator tmp = _it;
		return *(--tmp);
	}

	Ptr operator->()
	{
		return &(operator*());
	}

	Self& operator++()//前置++
	{
		--_it;
		return *this;
	}

	Self& operator--()//前置--
	{
		++_it;
		return *this;
	}

	Self operator++(int)//后置++
	{
		Iterator tmp = _it;
		++_it;
		return tmp;
	}

	Self operator--(int)//后置--
	{
		Iterator tmp = _it;
		--_it;
		return tmp;
	}

	bool operator!= (const Self& s) const
	{
		return _it != s._it;
	}

	bool operator==(const Self& s)const
	{
		return _it == s._it;
	}
private:
	Iterator _it;
};

list里面对反向迭代器的适配

image-20230112091913394

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

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

相关文章

微信转账api(企业付款)

企业付款介绍 提供企业向用户付款的功能&#xff0c;支持企业通过API接口付款&#xff0c;或通过微信支付商户平台网页功能操作付款。 1. 充值 登录微信支付商户平台&#xff0c;通过网页充值功能充值&#xff08;商户平台-资金管理-现金管理-充值&#xff09;。 温馨提示&a…

BreederDAO x DigiCult AMA——要点总结

问&#xff1a;为什么 BreederDAO 决定花费 200ETH 用于购买 Mythic DigiDaigaku Genesis — Ifrit&#xff1f; 答&#xff1a;除了投资之外&#xff0c;这也是为了确保这个领域中有更多的可触达性&#xff0c;尤其是随着我们 DigiDaigaku 市场工具的推出之后。这也是我们进入…

(十七)Async异步和多线程-语言进阶1

&#xff08;十七&#xff09;Async异步和多线程-语言进阶1一、进程-线程-多线程&#xff0c;同步和异步1.概念2.同步和异步3.异步与多线程异同点二、委托启动异步调用1.同步方法2.异步方法三、多线程的特点四、异步的回调和状态参数1.顺序控制2.状态参数五、异步等待三种方式1…

开学季,护眼灯什么牌子好?2023年护眼台灯推荐

2023年开始了&#xff0c;时间飞逝&#xff0c;而每个父母都越来越紧张自家娃的学业情况&#xff0c;我国近视人数超过7亿人&#xff0c;而儿童时期是视力发育的关键时期&#xff0c;为啥有那么高的近视率呢&#xff1f;主要是用眼过度&#xff0c;以及用眼习惯&#xff0c;而现…

微信小程序——模板与配置,数据绑定,事件绑定

一.数据绑定1.数据绑定的基本原则在data中定义数据在WXML中使用数据2.在data中定义页面的数据在页面对应的.js文件中&#xff0c;把数据定义到data对象中即可3. Mustache 语法的格式把 data 中的数据绑定到页面中渲染&#xff0c;使用 Mustache 语法&#xff08;双大括号&#…

想提高办公效率?可试试java开源工作流框架

在数据化管理越来越规范的当今社会&#xff0c;采用优质的办公软件平台能提高企业的办公协作效率&#xff0c;因而受到了广泛的欢迎和喜爱。那么&#xff0c;什么是java开源工作流框架&#xff1f;我们可以从它的特点、发展前景等方面来加以了解&#xff0c;一起来了解这一产品…

微信公众号运营工具有哪些?赶紧收藏

再厉害的公众号运营大神背后都有一套宝藏工具大全&#xff0c;辅助运营人一路披荆斩棘&#xff0c;堪称神器&#xff01; 我相信网上一搜也能出来很多的运营工具或是网站&#xff0c;但是这里再来给大家来一个大汇总&#xff0c;这次整理绝对是非常详细和实用的&#xff0c;纯…

Fiddler中常用的功能

Fiddler中常用的功能如下&#xff1a; 停止抓包-清空会话窗-内容过滤请求-解码-设置断点 一、 停止抓包 二、清空会话窗 方法一&#xff0c;工具栏工具&#xff1a; 方法二&#xff0c;命令行形式&#xff1a; 当然&#xff0c;命令行工具也还支持其他命令的输入&#xff0c…

word排版技巧:如何将段中文字生成标题目录

在许多Word文档里面&#xff0c;目录页是非常重要的一页内容&#xff0c;因为目录页展示的是当前文档的内容框型和结构。通过目录页&#xff0c;我们能知道这个文档主要分为哪几部分。就像看书一样&#xff0c;起到了检索的作用。今天&#xff0c;我们就来给大家分享一个偏门的…

焕新古文化传承之路,AI为古彝文识别赋能

目录1 古彝文与古典保护2 古文识别的挑战2.1 西文与汉文OCR2.2 古彝文识别难点3 合合信息&#xff1a;古彝文保护新思路3.1 图像矫正3.2 图像增强3.3 语义理解3.4 工程技巧4 总结1 古彝文与古典保护 彝文指的是云南、贵州、四川等地的彝族人使用的文字&#xff0c;区别于现代意…

【Linux】常用基本指令(续)

文章目录&#x1f3aa; Linux下基本指令1.1 &#x1f680; whoami1.2 &#x1f680; tree1.3 &#x1f680; echo(浅析)1.4 &#x1f680; zip/unzip1.5 &#x1f680; tar1.6 &#x1f680; bc1.7 &#x1f680; history1.8 &#x1f680; uname1.9 &#x1f680; nano1.10 &a…

数据结构基础之动态顺序表详解

文章目录前言一、动态顺序表的概念二、顺序表的结构体三、基本接口1.SeqListInit&#xff08;初始化数组&#xff09;2.SeqListDestory&#xff08;销毁数组&#xff09;3. SeqListCheckCapacity&#xff08;检查改顺序表是否需要扩容&#xff09;4.SeqListPushBack&#xff08…

用真实业务场景告诉你,高并发下如何设计数据库架构?

目录&#xff1a; 用一个创业公司的发展作为背景引入用多台服务器来分库支撑高并发读写大量分表来保证海量数据下查询性能读写分离来支撑按需扩容及性能提升高并发下的数据库架构设计总结 这篇文章&#xff0c;我们来聊一下对于一个支撑日活百万用户的高并系统&#xff0c;他…

如何搭建云进销存-销售管理系统?

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建云进销存-销售管理。1.2、应用场景云进销存-销售管理应用支持移动端扫码录入&#xff0c;提高开单效率&#xff0c;保证开单质量。支持自定义优先级自动取价&#xff0c;灵活满足不同商品价格管理。2、设置方法2.1、表单搭建…

马蹄集 大小写的转换

大小写的转换 难度&#xff1a;青铜 0时间限制&#xff1a;1秒 巴占用内存&#xff1a;64M 请编写一个简单程序&#xff0c;实现输入字符大小写的转换。其他非法输入&#xff08;非 字母的输入)则原样输出。 #include <bits/stdc.h> using namespace std; int main() { …

1700页!卷S人的 Java《八股文》PDF手册

2022已成为过去式&#xff0c;不论这一年好与坏&#xff0c;我们都需要抓住新一年的机会&#xff0c;不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&#xff0c;给大家搞…

Java关键字synchronized

提纲 定义 synchronized是同步块&#xff0c;实现了多线程间的互斥同步。它修饰的代码&#xff0c;确保任一时刻只有一个线程进入访问。 特性 因为在synchronized同步块内&#xff0c;只有一个线程能访问&#xff0c;因此确保了同步块内的原子性、可见性和有序性。 使用方式 总…

SpringBoot 统⼀功能处理 AOP

接下来是 Spring Boot 统⼀功能处理模块了&#xff0c;也是 AOP 的实战环节&#xff0c;要实现的⽬标有以下 3 个&#xff1a; 统⼀⽤户登录权限验证&#xff1b;统⼀数据格式返回&#xff1b;统⼀异常处理。 1.⽤户登录权限效验 ⽤户登录权限的发展从之前每个⽅法中⾃⼰验…

day35【代码随想录】贪心算法之加油站、分发糖果、柠檬水找零

文章目录前言一、加油站&#xff08;力扣134&#xff09;方法一方法二二、分发糖果&#xff08;力扣135&#xff09;三、柠檬水找零&#xff08;力扣860&#xff09;前言 1、加油站 2、分发糖果 3、柠檬水找零 一、加油站&#xff08;力扣134&#xff09; 在一条环路上有 n 个…

好文推荐!LLM技术精要;美图发全员激励股✦票;百度/微信大会精华笔记;Flink商✦业化再起波澜;GitHub今日热榜 | ShowMeAI资讯日报

&#x1f440;日报合辑 | &#x1f3a1;AI应用与工具大全 | &#x1f514;公众号资料下载 | &#x1f369;韩信子 &#x1f3a1; 『通向 AGI 之路』大型语言模型&#xff08;LLM&#xff09;技术精要 实话实说&#xff0c;国内在 LLM 模型相关技术方面&#xff0c;此刻距离最先…