STL中priority_queue自定义类型使用和源码简单分析

news2024/11/17 6:36:05

priority_queue使用

这里说一下优先级队列的其他的用法,这里我们先看默认的究竟是建立大堆还是小堆?

#include <iostream>
#include <queue>

int main()
{
	int arr[] = { 10, 2, 1, 3, 5, 4, 0 };
	std::priority_queue<int> q;
	for (size_t i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
	{
		q.push(arr[i]);
	}
	while (!q.empty())
	{
		std::cout << q.top() << " ";
		q.pop();
	}
	return 0;
}

image-20230505184108402

是大堆,那么我们应该如何让他建立成小堆呢?先来它他们的构造函数.

image-20230505184310699

这个是C++98的,我们发现这里有两个,这里测试第一个,我们发现comp是一个对象,此时我们就想到了仿函数对象,那么是不是呢?直接测试.

#include <iostream>
#include <queue>
#include <vector>

int main()
{
	int arr[] = { 10, 2, 1, 3, 5, 4, 0 };
	std::priority_queue<int, std::vector<int>, std::less<int>> q;
	for (size_t i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
	{
		q.push(arr[i]);
	}
	while (!q.empty())
	{
		std::cout << q.top() << " ";
		q.pop();
	}
	return 0;
}

image-20230505185105814

那么greater就是小根堆了,测试一下.

#include <iostream>
#include <queue>
#include <functional>

int main()
{
	int arr[] = { 10, 2, 1, 3, 5, 4, 0 };
	std::priority_queue<int, std::vector<int>, std::greater<int>> q;
	for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		q.push(arr[i]);
	}
	while (!q.empty())
	{
		std::cout << q.top() << " ";
		q.pop();
	}
	return 0;
}

image-20230505185548744

下面我们测试一下自定义类型的入堆操作,这里我们直接写出一个仿函数.

struct node
{
	int x;
	int y;
};

struct cmp
{
	bool operator()(const node& n1, const node& n2){
		return n1.x > n2.x;
	}
};
int main()
{
	node n1 = { 1, 2 };
	node n2 = { 2, 4 };
	node n3 = { 3, 4 };
	priority_queue<node, vector<node>, cmp>q;
	q.push(n1);
	q.push(n2);
	q.push(n3);
	
	return 0;
}

image-20230505190359053

如果我们要是不想写仿函数,那么我们在结构体里面重载<操作符,看大家的喜好吧.

struct node
{
	int x;
	int y;
	bool operator<(const node& n) const
	{
		return x > n.x; // 这里可以控制是大堆还是小堆
	}
};


int main()
{
	node n1 = { 1, 2 };
	node n2 = { 2, 4 };
	node n3 = { 3, 4 };
	priority_queue<node>q;
	q.push(n1);
	q.push(n2);
	q.push(n3);

	return 0;
}

image-20230505190749801

priority_queue源码

这里我们简单的分析一下源码,主要是加深一下印象.

template <class T, class Sequence = vector<T>, 
          class Compare = less<typename Sequence::value_type> >
class  priority_queue {
public:
  typedef typename Sequence::value_type value_type;
  typedef typename Sequence::size_type size_type;
  typedef typename Sequence::reference reference;
  typedef typename Sequence::const_reference const_reference;
protected:
  Sequence c;
  Compare comp;
public:
  priority_queue() : c() {}
  explicit priority_queue(const Compare& x) :  c(), comp(x) {}
    
  void push(const value_type& x) {
    __STL_TRY {
      c.push_back(x); 
      push_heap(c.begin(), c.end(), comp);
    }
    __STL_UNWIND(c.clear());
  }
};

先来得到第一个结论

image-20230505193444548

试一下上面我们说的,新的构造方式,不过我们很少用.

struct node
{
	int x;
	int y;
};

struct cmp
{
	bool operator()(const node& n1, const node& n2){
		return n1.x > n2.x;
	}
	cmp(const cmp& c)
	{

	}
	cmp()
	{

	}
};
int main()
{
	node n1 = { 1, 2 };
	node n2 = { 2, 4 };
	node n3 = { 3, 4 };
	cmp c;
	priority_queue<node, vector<node>, cmp> q(c);
	q.push(n1);
	q.push(n2);
	q.push(n3);

	return 0;
}

image-20230505194000255

下面我们来谈当我们数据进入数组的时候,我们调整堆的操作,这里不做具体的分析,就谈为何我们的重载了<就不用写仿函数了,应该是这个函数,我们直接来分析一下吧.

template <class RandomAccessIterator, class Distance, class T, class Compare>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
                 Distance topIndex, T value, Compare comp) {
  Distance parent = (holeIndex - 1) / 2;
  while (holeIndex > topIndex && comp(*(first + parent), value)) {
    *(first + holeIndex) = *(first + parent);
    holeIndex = parent;
    parent = (holeIndex - 1) / 2;
  }
  *(first + holeIndex) = value;
}

首先我们调用的是默认的无参构造函数,此时我们的Compare的实际类型是less<Node>,后面我们使用比较的,那么此时我们使用的就是less类型的,也就是我们的标准提供的仿函数.

image-20230505194426639

struct node
{
	int x;
	int y;
	bool operator<(const node& n) const
	{
		return x > n.x; // 这里可以控制是大堆还是小堆
	}
};


int main()
{
	node n1 = { 1, 2 };
	node n2 = { 2, 4 };
	node n3 = { 3, 4 };
	priority_queue<node>q;
	q.push(n1);
	q.push(n2);
	q.push(n3);

	return 0;
}

下面就到了观察less类型了,我们这里继续进去看.

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

看到了吗.这里面重载了括号,看到函数体内存在一个<吗?这里调用的就是我们在Node中写的<重载操作符,这里就是我们为何是这样的.那么此时我们也可以重载>,看下面的操作.

struct node
{
	int x;
	int y;
	bool operator>(const node& n) const
	{
		return x > n.x; 
	}
};


int main()
{
	node n1 = { 1, 2 };
	node n2 = { 2, 4 };
	node n3 = { 3, 4 };
	priority_queue<node, vector<node>, greater<node>>q;
	q.push(n1);
	q.push(n2);
	q.push(n3);

	return 0;
}

image-20230505195616847

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

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

相关文章

基于springboot的私人健身与教练预约管理系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代…

计算机网络学习笔记-概述

目录 信息时代 互联网 因特网发展的三个阶段 制定互联网的正式标准阶段 互联网组成&#xff1a;边缘部分核心部分 边缘部分 核心部分 计算机网络 体系结构 OSI 七层参考模型&#xff1a;物理层 数据链路层 网络层 运输层 会话层 表示层 应用层 TCP/IP 4层参考模型&a…

【K8S系列】深入解析k8s网络

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 Kubernetes (k8s) 是一个容器编排平台&#x…

(8) 支持向量机分类器SVC案例:预测明天是否会下雨

文章目录 案例介绍1 导库导数据&#xff0c;探索特征2 分集&#xff0c;优先探索标签3 探索特征&#xff0c;开始处理特征矩阵3.1 描述性统计与异常值3.2 处理困难特征&#xff1a;日期3.3 处理困难特征&#xff1a;地点3.4 处理分类型变量&#xff1a;缺失值3.5 处理分类型变量…

Typora + PicGo + Gitee 搭建免费图床

搭建准备 本次搭建过程需要以下介质&#xff1a;Typora PicGo Gitee/GitHub &#xff0c;「免费&#xff01;」 Typora Typora 是一款 markdown 编辑器&#xff0c;支持几乎所有的 markdown 格式&#xff0c;神器&#xff01; 支持 macOS、Windows、Linux 三种操作系统&am…

Composition API 的优势、新的组件(Fragment,Teleport,Suspense)【Vue3】

四、Composition API 的优势 1. Options API 存在的问题 使用传统OptionsAPI中&#xff0c;新增或者修改一个需求&#xff0c;就需要分别在data&#xff0c;methods&#xff0c;computed里修改。 2. Composition API 的优势 我们可以更加优雅的组织我们的代码&#xff0c…

Packet Tracer - 在思科路由器上配置 AAA 认证

Packet Tracer - 在思科路由器上配置 AAA 认证 拓扑图 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 交换机端口 R1 G0/1 192.168.1.1 255.255.255.0 不适用 S1 F0/1 S0/0/0 (DCE) 10.1.1.2 255.255.255.252 不适用 不适用 R2 G0/0 192.168.2.1 255.2…

(4)基本组件

目录 1. Designer 设计师** 2. Layout 布局*** 3. 基本组件 3.1 QWidget** 3.2 ui指针 3.3 QLabel 标签** 3.4 QAbstractButton 按钮类** 示例 1. Designer 设计师** Designer是一款独立的用于设计Qt界面的应用程序。 Designer程序保存的文件格式为.ui&#xff0c;这是Qt中的界…

腾讯云轻量应用服务器修改镜像系统有哪些限制?

腾讯云轻量应用服务器镜像可以更换或修改吗&#xff1f;可以&#xff01;镜像可以修改&#xff0c;镜像是指轻量服务器的预装操作系统&#xff0c;轻量服务器创建成功后镜像也是可以更换的。 镜像是轻量服务器的预装操作系统&#xff0c;轻量应用服务器的镜像不仅包含操作系统&…

看我如何通过帮助服务台轻松黑掉数百家公司

导语&#xff1a;几个月前&#xff0c;我发现黑客可以利用一个漏洞访问目标公司的内部通信。 这个漏洞只需要点击几下&#xff0c;就可以访问企业内部网络、 Twitter等社交媒体账户&#xff0c;以及最常见的Yammer和Slack团队。 更新: The Next Web 写了一篇我发现的这个漏洞的…

SAP BusinessObjects BI crack

SAP BusinessObjects BI crack 通过基于驱动程序标准的数据库、报告工具&#xff0c;甚至自定义应用程序&#xff0c;加入SAP BusinessObjects BI报告和分析。 与BI分析、报告、ETL工具和自定义解决方案集成。 SAP BusinessObjects BI奇妙功能中的CData驱动程序&#xff1a; BI…

数据结构与算法基础(王卓)(35):交换排序之快排【第一阶段:第一遍遍历】

目录 快速排序&#xff1a; 法一&#xff1a; 法二&#xff1a;&#xff08;常用、重难点&#xff09; 第一阶段&#xff1a;第一遍遍历 Project 1: 问题&#xff1a; Project 2: 问题&#xff1a; Project 3: 问题&#xff1a; Project 4: Project 5: 快速排序&am…

spring-模型数据和视图---视图解析器的说明以及大量代码演示

目录 spring-模型数据 ● 说明 应用实例需求 创建后面所有代码执行成功之后跳转的vote_ok.jsp页面 方式 1: 通过 HttpServletRequest放入 request 域 创建 Master类 创建Pet类 创建model_data.jsp 修改 VoteHandler增加方法 创建vote_ok.jsp, 显示数据 完成测试(Post…

初级算法-动态规划

主要记录算法和数据结构学习笔记&#xff0c;新的一年更上一层楼&#xff01; 初级算法-动态规划 一、斐波那契数二、爬楼梯三、使用最小花费爬楼梯四、不同路径五、不同路径二六、整数拆分七、不同的二叉搜索树八、0-1背包九、分割等和子集十、最后一块石头的重量十一、目标和…

深入浅出分支语句—【C语言】

目录 前言&#xff1a;为什么要学习分支和循环语句呢&#xff1f; 1. 语句的分类 2. 分支语句&#xff08;选择语句&#xff09; 2.1 if-else语句 注意点&#xff1a;if-else语句后面不加{}&#xff0c;默认只能跟一条语句 2.2 switch语句 注意点&#xff1a; 前言&…

平衡二叉树旋转机制

概念 平衡二叉树的旋转机制是一种通过对树进行旋转操作来保持其平衡的方法。 分类 平衡二叉树的旋转机制包括两种基本类型的旋转&#xff1a;左旋和右旋&#xff0c;以及它们的组合。 左旋 左旋是将一个节点的右子节点旋转到它的位置上&#xff0c;同时将该节点移到其左侧&…

关于低代码开发,你是真的了解了吗?

在低代码开发已是大势所趋的今天&#xff0c;不少企业都切身感受到了低代码开发带来的便利。低代码开发平台的优势在当下数字化浪潮中&#xff0c;为企业提供了定制专属的数字化解决方案。 低代码本身没有太强的行业属性&#xff0c;这也让低代码开发平台能够更加灵活地适应不同…

嵌入式 QT 界面布局管理

目录 1、实例程序功能 2、界面组件布局 2.1 界面组件的层次关系 2.2 布局管理 2.3 伙伴关系和Tab顺序 1、实例程序功能 创建一个 Widget Application 项目 samp2_2&#xff0c; 在创建窗体时选择基类 QDialog &#xff0c;生成的类命名为 QWDialog &#xff0c;并选择…

Python实用记录(十三):python脚本打包exe文件并运行

文章目录 打包准备文件准备环境安装 具体运行第一步第二步第三步 注意 打包准备 文件准备 这里准备一个简单的python代码&#xff08;打开电脑摄像头&#xff09; import cv2 if __name__ __main__:cap cv2.VideoCapture(0)ret, frame cap.read()while ret:ret, frame c…

希亦洗地机和添可洗地机哪个好用?口碑洗地机详细对比

在当今这个科技发达的社会&#xff0c;为了能够帮助人们高效率的工作&#xff0c;各色各样的发明不断出现。扫地、拖地是我们日常生活中再普通不过的一项家务了&#xff0c;对于小型的房子而言打扫起来就比较轻松&#xff0c;对于繁忙的上班族打扫空间较大的房子就很困难&#…