【C++】priority_queue和仿函数

priority_queue翻译过来就是优先队列,其实就是我们数据结构中的。堆这个东西之前也说过,它分为大根堆和小根堆它的底层是一个类似数组的连续的空间,逻辑结构是一个完全二叉树,这个完全二叉树如果是小根堆的话父亲小于孩子。两兄弟之间没有关系,两个比较关键的操作就是向上调整和向下调整,在建堆和出数据的时候很关键。

下面我们来复习一下向上调整和向下调整

void adjustup(int* a, int n) {
	for (int i = 1; i < n; i++) {
		int j = i;
		int parent = (j - 1) / 2;
		while (parent >= 0) {
			if (a[j] < a[parent]) {
				swap(a[j], a[parent]);
			}
			else break;
			j = parent;
			parent = (j - 1) / 2;
		}
	}
}

void adjustdown(int* a, int n, int pos) {
	int child = pos * 2 + 1;
	while (child < n) {
		if (child + 1 < n && a[child] > a[child + 1])child++;
		if (a[child] < a[pos])swap(a[child], a[pos]);
		else break;
		pos = child;
		child = child * 2 + 1;
	}
}

这就是我们之前学的,我们要排升序要建大堆,排降序要建小堆,那我们来看看C++库里是怎么弄的

这也是一个容器适配器,容器的缺省值用的vector,因为这种结构建起堆来是比较容易的,这跟我们原来学的用数组也是一样的道理,第三个模板参数是一个用来比较的模板参数,这个参数是一个类,缺省值是用的less,默认是建大堆。文档中也有介绍

我们要是想建小堆则要改变第三个模板参数,而它是一个类,所以我们要传一个类进去,就是我们上边的greater<int>,我们要传第三个就要传第二个,这是缺省值的语法规则限制的:给缺省值要从右向左依次给,传参数时从左向右依次匹配。

我么说了,第三个模板参数传了一个类,一个类怎么实现一个比较函数的功能呢?(我们之前不就是传一个函数指针,比如qsort,用回调函数)

因为一个类它并不是函数,所以叫仿函数,或者叫函数对象(它是一个类实例化的一个对象,有函数的功能),我们也可以随随便便写一个仿函数

所以它的关键就是重载了括号,使它的对象可以用括号这个操作符,从而就像函数一样,我们下边模拟实现的时候建大堆还是小堆都是跟库中一样通过传一个类来实现的

下面是一个找数组中最大的第k个数的问题,用C++写就方便了很多

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> pq(nums.begin(),nums.begin() + k);
        auto it = nums.begin() + k;
        while (it != nums.end()) {
            if (*it > pq.top()) {
                pq.pop();
                pq.push(*it);
            }
            it++;
        }
        return pq.top();
    }
};

用法讲完了,下面我们来模拟实现一下

namespace jxh {
	template<class T, class container = vector<T>, class compare = less<T>>
	class priority_queue {
	public:
		void adjustup(int child) {
			compare com;
			int parent = (child - 1) / 2;
			while (parent >= 0) {
				if (com(_con[child] , _con[parent])) {
					std::swap(_con[child], _con[parent]);
				}
				else break;
				child = parent;
				parent = (child - 1) / 2;
			}
		}
		void adjustdown(int parent) {
			compare com;
			int n = _con.size();
			int child = parent * 2 + 1;
			while (child < n) {
				if (child + 1 < n &&  com(_con[child + 1], _con[child]))child++;
				if (com(_con[child] , _con[parent]))std::swap(_con[child], _con[parent]);
				else break;
				parent = child;
				child = child * 2 + 1;
			}
		}
		void push(const T& x) {
			_con.push_back(x);
			adjustup(_con.size() - 1);
		}
		void pop() {
			std::swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjustdown(0);
		}
		const T& top() {
			return _con[0];
		}
		bool empty() {
			return _con.empty();
		}
		size_t size() {
			return _con.size();
		}

	private:
		container _con;
	};
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高效实用|ChatGPT指令/提示词/prompt/AI指令大全,进阶版

大家好&#xff0c;我是淘小白~ 《高效实用|ChatGPT指令/提示词/prompt/AI指令大全&#xff0c;基础版》整理完了&#xff0c;下面来看下进阶版的吧&#xff01; 如果对你有用记得点赞、关注、收藏哦~ 划走可能找不着了哦~~ 进阶版指令可用于复杂任务和场景&#xff0c;以及…

01背包问题 刷题笔记

思路 dp 用f[i][j]来表示当体积为j时 考虑前i件物品可以获得的 最大值 记住f[i][j]本身是个价“价值” 考虑两种状态 是否将第i件物品放入背包里面 将背包的体积从小到大递增来进行考虑 首先 考虑条件 如果当前增加的体积放不下下一件物品 则该体积 可以获得的最大值可以直接…

通义灵码-智能编码辅助工具

1.介绍 通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;并针对阿里云 SDK/OpenAPI 的使用场景调优&a…

经典语义分割(二)医学图像分割模型UNet

经典语义分割(二)医学图像分割模型UNet 我们之前介绍了全卷积神经网络( FCN) &#xff0c;FCN是基于深度学习的语义分割算法的开山之作。 今天我们介绍另一个语义分割的经典模型—UNet&#xff0c;它兼具轻量化与高性能&#xff0c;通常作为语义分割任务的基线测试模型&#x…

Unity 动画(旧版-新版)

旧版 旧版-动画组件&#xff1a;Animation 窗口-动画 动画文件后缀: .anim 将制作后的动画拖动到Animation组件上 旧版的操作 using System.Collections; using System.Collections.Generic; using UnityEngine;public class c1 : MonoBehaviour {// Start is called before…

【Python】6. 基础语法(4) -- 列表+元组+字典篇

列表和元组 列表是什么, 元组是什么 编程中, 经常需要使用变量, 来保存/表示数据. 如果代码中需要表示的数据个数比较少, 我们直接创建多个变量即可. num1 10 num2 20 num3 30 ......但是有的时候, 代码中需要表示的数据特别多, 甚至也不知道要表示多少个数据. 这个时候,…

SAP - 采购价格确定 ③ 抬头条件和组条件

抬头条件和组条件 当我们创建一个具有多个行项目的采购订单时,我们经常需要条件可以应用到所有的行项目中。相应的,条件也可以应用到特定的行项目。在R/3系统中,条件可以涉及采购凭证的单个行项目(项目条件),多个行项目(组条件)或所有的行项目(抬头条件)。 一些标准…

day14_异常

今日内容 零、 复习昨日 一、日期类 二、异常 零、 复习昨日 1为什么要重写toString Object类toString返回的是对象名字地址,无意义子类重写toString() 返回的对象属性内容 2为什么要重写equals Object类equals判断是对象的地址值是否相等,无意义子类重写equals,为了判断对象的…

贪心算法详解及机器人运动应用Demo

一、引言 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效。今天&#xff0c;我们将通过一个机器人运动的Demo来详细解析贪心算…

Vision Transformer结构解析

Vision Transformer结构解析 ViT简介ViT三大模块ViT图像预处理模块——PatchEmbed多层Transformer Encoder模块MLP&#xff08;FFN&#xff09;模块 基本的Transformer模块Vision Transformer类的实现Transformer知识点 ViT简介 Vision Transformer。transformer于2017年的Att…

【计算机考研】考408,还是不考408性价比高?

首先综合考虑&#xff0c;如果其他科目并不是很优秀&#xff0c;需要我们花一定的时间去复习&#xff0c;408的性价比就不高&#xff0c;各个科目的时间互相挤压&#xff0c;如果备考时间不充裕&#xff0c;考虑其他专业课也未尝不可。 复习408本来就是费力不讨好的事情 不同…

支小蜜校园防欺凌报警系统如何识别霸凌

校园霸凌给受害者带来了深重的心理和身体伤害。为了有效应对这一问题&#xff0c;校园防欺凌报警系统应运而生&#xff0c;其核心技术在于如何准确、迅速地识别霸凌行为。那么校园防欺凌报警系统是如何识别霸凌的呢&#xff1f; 图像识别技术 这些系统利用高清摄像头捕捉校园…

洛谷P2233 公交车路线

本题题号特殊&#xff0c;相对简单。 题目描述 在长沙城新建的环城公路上一共有 88 个公交站&#xff0c;分别为 A、B、C、D、E、F、G、H。公共汽车只能够在相邻的两个公交站之间运行&#xff0c;因此你从某一个公交站到另外一个公交站往往要换几次车&#xff0c;例如从公交站…

【uni-app小程序开发】实现一个背景色渐变的滑动条slider

最近做的一个用uni-app+vue2开发的微信小程序项目中要实现一个滑动进度控制条,如下图所示: 1. 滑动条需要渐变背景色 2. 滑块的背景色需要与当前位置滑动条的背景色一致(动态改变) 碰到这样的需求,我当然先是看看官方提供的slider组件和uView里的u-slider组件能不能满足…

网络学习:Vlan基础知识、划分思路及其优越性

目录 一、VLAN基础知识 二、VLAN的划分方法 1. 基于端口划分的VLAN 2. 基于MAC地址划分VLAN 3. 基于网络层协议划分VLAN 4. 根据IP组播划分VLAN 5. 按策略划分VLAN 6. 按用户定义、非用户授权划分VLAN 三、VLAN的优越性 1. 增加了网络连接的灵活性 2. 控制网络上的广…

根据标准化开发流程---解析LIN总线脉冲唤醒的测试方法和用例设计思路

前言&#xff1a;本文从标准化开发流程的角度&#xff0c;以LIN总线脉冲唤醒为切入点。从测试工程师的角度来讲测试工作应当如何展开&#xff08;结合我干测试总结出来的测试经验&#xff09;。希望大家都能从中有收获&#xff01;&#xff01;谢谢&#xff01;&#xff01; 1…

进程:守护进程

一、守护进程的概念 守护进程是脱离于终端控制&#xff0c;且运行在后端的进程。&#xff08;孤儿进程&#xff09;守护进程不会将信息显示在任何终端上影响前端的操作&#xff0c;也不会被终端产生的任何信息打断&#xff0c;例如&#xff08;ctrlc&#xff09;.守护进程独立…

Endnote 参考文献 序号对齐

问题描述&#xff1a;想要Engnote插入的参考文献需要后自动对齐&#xff0c;不需要悬挂缩进&#xff0c;悬挂缩进会导致中文和英文文献也对不齐&#xff0c;还有就是参考文献序号从9变成10的时候也会导致文献无法对其。 解决办法&#xff1a; 打开Enfdnote&#xff0c;点击Too…

配置nvm管理nodejs版本的环境详细教程【window版】

nvm( node.js version management) 是 Windows 系统下的一个 Node.js 版本管理工具&#xff0c;它是 Node Version Manager&#xff08;nvm&#xff09;的 Windows 版本&#xff0c;它是基于GO语言开发的工具。该工具允许你在 Windows 系统上轻松地安装、切换和管理多个 Node.j…

网络编程套接字(1)—网络编程基础

目录 一、为什么需要网络编程? 二、什么是网络编程 三、网络编程中的基本概念 1、发送端和接收端 2、请求和响应 3、客户端和服务端 四、常见的客户端服务端模型 1、一问一答模型 2、一问多答模型 3、多问一答模型 4、多问多答模型 一、为什么需要网络编程? 为什么…