优先级队列的实现

news2024/11/14 17:04:13

什么是优先级队列

优先级队列是一种特殊的数据结构,它类似于队列或栈,但是每个元素都关联有一个优先级或权重。在优先级队列中,元素的出队顺序不是简单地按照它们进入队列的先后顺序(先进先出,FIFO),而是根据元素的优先级来决定。具有最高优先级的元素最先出队,如果两个元素具有相同的优先级,则按照它们在队列中的顺序出队。
通俗来说,假设我们传入队列的是整形数据,那么他会按照数据的从小到大还是从大到小的出队顺序存放在队列中这就是优先级队列

仿函数

这里要提到一个概念叫仿函数
仿函数是一个可以像函数一样调用的对象。简单来说,仿函数是一种具有operator()成员函数的对象,使得该对象可以像普通函数一样使用调用操作符(),他是重载operator()括号实现的,我们来举个例子
下面是个比较大小的仿函数例子

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

这里我们利用这个比较大小的仿函数,就可以像函数那样调用,就像这样

int main()
{
  less li;
  if(li(1,2))
  {
  cout<<"y比x大"<<endl;
  }
  else
 {
 cout<<"x比y大"<<endl;
 }
  return 0;
  }

在举个形象的例子

# include<iostream>
# include<string>
using namespace std;
template<class type>
class _cout
{
public:
	void operator()(const type& input)
	{
		cout << input << endl;
	}
};
int main()
{
	_cout<string> print;
	print("hello,word");
	return 0;
}

有了以上仿函数的介绍之后,就可以开始说我们的优先级队列了

优先级队列的实现

优先级队列的实质上就是用堆来创建队列,按照堆排序的思想来对输入到队列里面的数据进行处理,按照升序建大堆,降序建小堆的思想进行创建,所以这里需要两个堆排序里面关键的函数**adjustdown(向下调整)adjustup(向上调整)**还需要我们上面提到的仿函数,这里仿函数的作用就是我们不用去改代码中的大于还是小于,直接在创建对象的时候提供模板参数就来作为创建大堆还是小堆的依据,非常方便
下面是仿函数

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

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

接下来是建堆算法

	template<class type,class contier = vector<type>,class compre = less<type>>
	class priorityqueue
	{
	public:
		void adjustup(size_t child)
		{
			compre com;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (com(_con[parent],_con[child]))
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void adjustdown(size_t parent)
		{
			compre com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//        x        <        y 
				if (child + 1 < _con.size() && com(_con[child], _con[child+1]))
				{
					child++;
				}
				//        x        <        y 
				if (com(_con[parent], _con[child]))
				{ 
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
void push(const type& input)
{
	_con.push_back(input);
	adjustup(_con.size() - 1);
}
void pop()
{
	swap(_con[0], _con[_con.size() - 1]);
	_con.pop_back();
	adjustdown(0);
}

这里需要结合这4个函数一起看,push就是插入数据,插入完之后,我们这里的默认容器是vector,然后我们调用向上建堆算法,从数组最后一位开始(所以这里的size()-1)vector下标是从零开始的存放10个数就是占用0-9个位置,假设我们插入1,9,2,10,3我们来画图看看是怎么调堆的
在这里插入图片描述这就是向上建堆的过程,也是我们push数据的过程
接下来说一说pop,出队列
这里需先出对顶数据在把第一个数据和最后一个数据进行交换
在这里插入图片描述
在向下调整堆
因为是建的大堆,把最大的数据给pop掉了之后,采用向下调整算法,第二大的数据就会出现在堆顶
在一直执行这个操作,最后的出队顺序就是从大到小的顺序
t1是创建的对象
出队列代码

	void test()
	{
		priorityqueue<int,vector<int>,less<int>> t1;
		t1.push(1);
		t1.push(9);
		t1.push(2);
		t1.push(10);
		t1.push(3);

		while (!t1.is_empty())
		{
			cout << t1.top() << " ";
			t1.pop();
	   }
	}

在这里插入图片描述最后还有剩下的这些小函数关于返回大小,容器空没有,取到堆顶的数据

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

源码

#pragma once
# include<vector>
# include<iostream>
using namespace std;
namespace thr
{ 
 template<class type>
  class less
 {
 public:
	bool operator()(const type& x, const type& y)
	{
		return x < y;
	}
};

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

	template<class type,class contier = vector<type>,class compre = less<type>>
	class priorityqueue
	{
	public:
		void adjustup(size_t child)
		{
			compre com;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				  //        x        <        y 
				if (com(_con[parent],_con[child]))
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void adjustdown(size_t parent)
		{
			compre com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//        x        <        y 
				if (child + 1 < _con.size() && com(_con[child], _con[child+1]))
				{
					child++;
				}
				//        x        <        y 
				if (com(_con[parent], _con[child]))
				{ 
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}
		void push(const type& input)
		{
			_con.push_back(input);
			adjustup(_con.size() - 1);
		}
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjustdown(0);
		}
		size_t size()
		{
			return _con.size();
		}
		bool is_empty()
		{
			return _con.empty();
		}
		const type& top()
		{
			return _con[0];
		}
	private:
		contier _con;
	};
	void test()
	{
		priorityqueue<int,vector<int>,less<int>> t1;
		t1.push(1);
		t1.push(9);
		t1.push(2);
		t1.push(10);
		t1.push(3);

		while (!t1.is_empty())
		{
			cout << t1.top() << " ";
			t1.pop();
	   }
	}
}

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

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

相关文章

vulnhub靶机 DC-9(渗透测试详解)

一、靶机信息收集 1、靶机下载 https://download.vulnhub.com/dc/DC-9.zip 2、靶机IP扫描 3、探测靶机主机、端口、服务版本信息 4、靶机目录扫描 二、web渗透测试 1、访问靶机IP 查看页面功能点&#xff0c;发现一个搜索框和登录框 2、测试一下是否存在sql注入 查看当前数…

快速解析数据挖掘,最短时间明白什么是数据挖掘------下

信息损失函数 &#xff08;Information Loss Function&#xff09;是衡量在数据转换或处理过程中信息丢失的程度的函数。在数据科学、机器学习和统计学中&#xff0c;信息损失是一个重要的概念&#xff0c;尤其是在数据降维、特征选择、数据压缩和隐私保护等领域。 信息损失函…

解密!抖音百万粉丝博主三维地图视频都用到了什么GIS数据和技术

引言 在抖音上有许多诸如三维地图科普局、三维地图看世界和三维地图鉴赏等百万粉丝博主靠着三维地图科普城市、景区、人文和地理视频获赞百万&#xff0c;在我们浏览视频时犹如身临其境一般&#xff0c;那么制作这些视频需要什么GIS技术呢&#xff1f;如何利用MapMost技术自己…

怎么防止源代码泄露?十种方法杜绝源代码泄密风险

源代码是软件开发的核心资产之一&#xff0c;保护其不被泄露对企业的安全至关重要。源代码泄露不仅可能导致知识产权的丧失&#xff0c;还可能给企业带来经济损失和品牌形象的损害。以下是十种有效的方法&#xff0c;可以帮助企业杜绝源代码泄密的风险。 1. 代码加密 对源代码…

LeetCode 3148.矩阵中的最大得分:每个元素与其左或上元素之差的最大值(原地修改O(1)空间)

【LetMeFly】3148.矩阵中的最大得分&#xff1a;每个元素与其左或上元素之差的最大值&#xff08;原地修改O(1)空间&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/maximum-difference-score-in-a-grid/ 给你一个由 正整数 组成、大小为 m x n 的矩阵 g…

ESVC论文笔记

ESVC: COMBINING ADAPTIVE STYLE FUSION AND MULTI-LEVEL FEATURE DISENTANGLEMENT FOR EXPRESSIVE SINGING VOICE CONVERSION阅读笔记 发现问题 虽然SVC在自然度和相似度方面都取得了很好的效果,但音频中除了歌手身份之外,情感表达也是传递歌手感情和态度的必要条件&#xf…

17.实现一个算法根据电话按键上的数字和字母的映射关系,输入一个或多个数字返回所有它能表示的全部字母组合

17. Letter Combinations of a Phone Number 题目 Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given belo…

电子音乐制作软件有哪些 电音制作用什么软件 好用的能够创作音乐的软件推荐 电音基础新手入门

电子音乐目前已经成为了年轻人的一大爱好&#xff0c;而全国各地随处可见的音乐节更是代表着电子音乐文化已经逐渐被年轻人所接受&#xff0c;在这样的大背景下&#xff0c;一些年轻人也开始了自己创作电子音乐的道路。现在有了软件的帮助&#xff0c;我们能够更加随心所欲的创…

卡码网KamaCoder 110. 字符串接龙

题目来源&#xff1a;110. 字符串接龙 C题解1&#xff1a;深度搜索。一条路径走到黑&#xff0c;并且记录到达当前节点的最短路径长度&#xff0c;不断更新&#xff0c;如果不是最短路径就不用再遍历那条路。 #include <iostream> #include <vector> #include <…

数据结构基本概念和术语

概论 1.1 基本概念和术语 1.1.1 基本概念 计算机处理的的是数值性数据&#xff0c;当计算机处理用户信息表中的数据的时候&#xff0c;需要弄清3个问题 1.数据的逻辑结构 数据之间存在怎样的内在联系&#xff0c;数据中&#xff0c;有且只有一个是首节点/尾结点&#xff0…

Squish 8.0现已发布

本文翻译自&#xff1a;Squish 8.0 Available Now 原文作者&#xff1a;Qt Group质量保证高级解决方案工程师Katarina Behrens 审校&#xff1a;Jinjing Li Squish团队非常激动地宣布Squish GUI Tester 8.0现已发布。对于自动化跨平台GUI测试而言&#xff0c;这是一款软件质量…

41-设计规则:线宽规则

1.设置电源线规则和信号线规则 2.设置信号线规则 3.设置电源线规则 如果未生效&#xff1a; ① 提升优先级即可。 ②查看使能选项有没有勾选

2024医疗器械网络交易服务第三方平台备案申请流程

前几天&#xff0c;小编给大家分享了药品网络交易第三方平台备案申请流程&#xff0c;好多客户就来问&#xff0c;那医疗器械网络交易服务第三方平台备案怎么办理呢&#xff1f; 今天&#xff0c;就给大家好好聊聊医疗器械网络交易服务第三方平台备案申请流程&#xff0c;供大…

Xilinx课程,就这么水灵灵地上线了~

如果你想了解&#xff1a; 如何利用精通流水线&#xff08;Pipeline&#xff09;技术&#xff0c;让电路设计效率倍增&#xff1f; 如何掌握利用性能基线指导设计流程的方法&#xff1f; 如何理解集成电路设计中的UltraFast Design Methodology Implementation设计方法学中的…

C++拾趣——编译器预处理宏__COUNTER__的应用场景

大纲 生成唯一标识符调试信息宏展开模板元编程代码 在C中&#xff0c;__COUNTER__是一个特殊的预处理宏&#xff0c;它主要被用来生成唯一的整数标识符。这个宏是由一些编译器&#xff08;如GCC和Visual Studio&#xff09;内置支持的&#xff0c;而不是C标准的一部分。它的主要…

《AI视频类工具之五——​ 开拍》

一.简介 官网:开拍 - 用AI制作口播视频用AI制作口播视频https://www.kaipai.com/home?ref=ai-bot.cn 开拍是一款由美图公司在2023年推出,利用AI技术制作的短视频分享应用。这款工具通过AI赋能,为用户提供了从文案创作、视频拍摄到视频剪辑、包装的一站式解决方案,极大地…

Using the ST-LINK/V2-1 to program and debug the STM32 on board

1. Using the ST-LINK/V2-1 to program and debug the STM32 on board To program the STM32 on the board, plug in the two jumpers on CN2 要对板上的STM32进行编程&#xff0c;请插入CN2上的两个跳线 2. 单片机供电 标有IDD的跳线JP6用于测量STM32微控制器的功耗 拆下跳…

UE5学习笔记14-动画的混合空间

零、我看视频中使用的是UE5.0左右的版本&#xff0c;我使用的是UE5.4&#xff0c;5.4中创建混合空间&#xff0c;没有看见有2D和3D混合动画空间的区分&#xff0c;具体的UE5如何创建2D的动画暂时不知道(我感觉现在创建的是3D的动画) 一、创建混合空间 1.我将所有的动画蓝图和动…

vue用户管理、角色管理和部门管理展示

1、用户和角色一对多&#xff0c;用户和部门多对多 2、用户管理 编辑用户时部门层级展示 角色-下拉框展示 <template><div class"s"><!-- 操作按钮 --><div class"shang"><el-input v-model"searchText" placeholde…

EXTI外部中断之对射式红外传感器计次应用案例

系列文章目录 STM32中断系统之EXTI外部中断 文章目录 系列文章目录前言一、应用案例简介二、电路接线图三、应用案例代码四、应用案例分析4.1 配置外部中断4.1.1 配置RCC时钟4.1.2 配置GPIO4.1.3 配置AFIO4.1.4 配置EXTI4.1.5 配置NVIC 4.2 编写中断函数 前言 提示&#xff1…