priority_queue优先级队列(堆)详解。C++经验+1

news2024/11/6 9:33:33

什么是堆

首先我们先了解什么是堆?堆分为大根堆和小根堆。但其实大根堆会让人误以为是不是大的元素在下面呢?为了防止错误想法,大根堆也可以叫大顶堆。

 大顶堆:顶上元素最大,上一层比下一层元素大。

小顶堆:顶上元素最小,上一层比下一层元素小。

什么是priority_queue优先级队列

priority_queue就是用vector 作为 模版,然后里面的数据填充的方法用的是堆算法。所以priority_queue就是堆。只不过是提供了对应接口的堆。不用手动去敲。

怎么定义priority_queue对象

方法一:默认定义(只指定是什么元素)

priority_queue<int> q;

默认定义:造出来的直接就是一个大顶堆。 

方法二:定义大顶堆(指定元素以及用什么当模版以及比较函数)

priority_queue<int, vector<int>, less<int>> q1;

上面不是说priority_queue用vector做模版吗?为什么这里我们还要写一遍。因为对于template模版 而言缺省值,只能从右给到左,如果要修改最后一个模版less<int>,那对应的前面的模版都得手动填写。

为什么大顶堆用less,因为less只是比较函数,比大小的和大顶堆的定义不冲突。可以想的是用less的话是小的元素往下跑。

方法三:定义小顶堆(指定元素以及用什么当模版以及比较函数)

priority_queue<int, vector<int>, greater<int>> q2;

 和大顶堆一样。

priority_queue的成员函数(方法接口)

成员函数功能
push插入元素到队尾(并排序)
pop弹出队头元素(堆顶元素)
top访问队头元素(堆顶元素)
size获取队列中有效元素个数
empty判断队列是否为空
swap交换两个队列的内容

用接口实现打印有序数组。

int main()
{
	priority_queue<int> q;
	q.push(3);
	q.push(6);
	q.push(0);
	q.push(2);
	q.push(1);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl; // 6 3 2 1 0
	return 0;
}

很简单,插入无序的元素,因为是大顶堆,所以最大的元素都在上面,每次弹出元素后,会把第二大的元素放到堆顶。以此循环直到没有元素。此时就是有序的。 

堆调整算法

上文说了priority_queue就是堆,那么堆算法里有两个核心:向上调整算法和向下调整算法

注意:虽然说是数组实现的,但是用二叉树的形式表示会更加明了。所以下面用二叉树的样子演示

向上调整算法:

顾名思义:就是把数据向上调整。对应的接口有:push。push时是将元素先插入堆的最后,在调用向上调整算法,找到其位置。

图一中每个节点右边的数字代表了节点在vector数组中的位置。

算法解析:插入元素后,让元素与其父节点比较,符合就替代父节点。以此往复直到不符合或者到达0位置。 

 代码如下:

//堆的向上调整(大堆)
void AdjustUp(vector<int>& v, int child)
{
	int parent = (child - 1) / 2; //通过child计算parent的下标
	while (child > 0)//调整到根结点的位置截止
	{
		if (v[parent] < v[child])//孩子结点的值大于父结点的值
		{
			//将父结点与孩子结点交换
			swap(v[child], v[parent]);
			//继续向上进行调整
			child = parent;
			parent = (child - 1) / 2;
		}
		else//已成堆
		{
			break;
		}
	}
}

向下调整算法:

顾名思义:就是将元素向下调整,那有什么用呢?在pop元素时。有两种思路:

1.删除最上面的元素后,对每个节点再做一次向上调整算法。这个时间复杂度挺高的。

2.将最上面的元素和最后面的元素交换,然后pop最后一个元素,将目前最上面的元素做一次向下调整。对比1快了许多。所以就有了向下调整算法。

和向上调整一样,都是比较元素。不同的在于这里是向下走,所以说比较时符号是相反的。当然也可以是两个操作数交换位置,就不用把符号改变了。可以实现代码的复用 

代码如下: 

//堆的向下调整(大堆)
void AdjustDown(vector<int>& v, int n, int parent)
{
    //child记录左右孩子中值较大的孩子的下标
    int child = 2 * parent + 1;//先默认其左孩子的值较大
    while (child < n)
    {
        if (child + 1 < n && v[child] < v[child + 1])//右孩子存在并且右孩子比左孩子还大
        {
            child++;//较大的孩子改为右孩子
        }
        if (v[parent] < v[child])//左右孩子中较大孩子的值比父结点还大
        {
            //将父结点与较小的子结点交换
            swap(v[child], v[parent]);
            //继续向下进行调整
            parent = child;
            child = 2 * parent + 1;
        }
        else//已成堆
        {
            break;
        }
    }
}

有了这两个调整算法以后,对于priority_queue的实现,就没什么问题了。 

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

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

相关文章

AI搜索软件哪个好,AI搜索引擎工具分享

随着AI技术的发展&#xff0c;AI搜索引擎工具正逐渐成为我们信息获取的重要方法。下面小编就来和大家分享一些好用的AI搜索引擎软件&#xff0c;感兴趣的同学可以逐个使用体验一下。因为每个AI搜索引擎工具不同&#xff0c;建议大家搜索的时候可以多个工具搜索&#xff0c;然后…

.netcore nacos注册成功,服务列表找不到任何服务

命令空间id不要自动生成 .netcore 配置文件里&#xff0c;Namespace 配置命名空间id 而不是命名空间名称。

OrangePi 烧录镜像步骤

理解&#xff1a;第一步&#xff1a;烧录镜像。第二步&#xff1a;建立编译环境&#xff08;一般是PC端的Linux虚拟机&#xff09;和板卡端的文件连接。因为要传文件&#xff0c;一般用挂载的方法。第三步&#xff1a;软件程序的编译与部署。 第一步&#xff1a;烧录镜像步骤 …

React学习笔记(四)——React 组件生命周期

目录 1. 生命周期-概览 2. 生命周期-挂载阶段 3. 生命周期-更新阶段 4. 生命周期-卸载阶段 5. setState扩展-发现问题 6. setState扩展-更多用法 7. setState扩展-异步 1. 生命周期-概览 了解react类组件生命周期整体情况 大致步骤&#xff1a; 什么是生命周期React类组…

AntFlow-Vue3 :一个仿钉钉流程审批,且满足99.8%以上审批流程需求的企业级工作流平台,开源且免费!

在现代企业管理中&#xff0c;流程审批的高效性直接影响到工作的流畅度与生产力。最近&#xff0c;我发现了一个非常有趣的项目—— AntFlow-Vue3 。这个项目不仅提供了一个灵活且可定制的工作流平台&#xff0c;还能让用户以可视化的方式创建和管理审批流程。 如果你是一名前…

10. 排序

一、排序的概念及引用 1. 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

Qt基础之四十七:管理员权限

在Windows系统中,以管理员身份运行的意思是,用系统管理最高权限运行程序。一般来说,只有当某些操作涉及系统保护区域时,才会需要用户授权管理员运行。如此一来,程序、命令在运行过程中,就有了足够权限,更改系统设置或注册表。 一.Qt程序加入管理员权限的几种方式 1.MS…

推荐一些免费下载恶意样本的网站

前一阵微步下载样本开始收费&#xff0c;算是又断了一个很好的白嫖途径。目前工作需求是不定期获取一批不同家族样本&#xff0c;看了看微步基础会员每天5次的下载限制&#xff0c;我默默把微步网页点了X&#xff0c;选择其他网站进行白嫖。 精确搜索 先列举出几个搜索比较简单…

【每天学个新注解】Day 6 Lombok注解简解(五)—@SneakyThrows

SneakyThrows 简化异常处理 并不建议日常开发中通过此注解解决异常捕获问题&#xff01;&#xff01;&#xff01; 允许方法抛出检查型异常而无需显式声明或捕获这些异常。这对于那些不希望在方法签名中声明异常或不愿意编写复杂的 try-catch 块的场景非常有用。 使用 SneakyT…

vue绘制评论页面

<template><div><div class"conmment_box"><div class"my-reply"><div class"reply-info"><el-inputfocus"focusInput"type"textarea"placeholder"请输入内容"v-model"tex…

LaTeX 编辑器-TeXstudio

TeXstudio 是一款开源跨平台 LaTeX 编辑软件&#xff0c;界面与 Texmaker 类似。TeXstudio 为用户提供互动式拼写检查、代码折叠、语法高亮、代码提示和自动完成等特性&#xff0c;功能丰富&#xff0c;界面美观&#xff0c;但软件本身不提供底层功能&#xff0c;需要使用者自行…

Qualcomm AI Hub模型优化1: Whisper-Base-En导出及问题解决

1 从Qualcomm AI Hub Module中选择Whisper-Base-En模块部署 1.1 进入module虚拟环境 python3 -m venv qai_hub_models_env && source qai_hub_models_env/bin/activate1.2 使用pip安装高通音频转录包 pip install "qai_hub_models[whisper_base_en]" 1.3…

C语言 | Leetcode C语言题解之第436题寻找右区间

题目&#xff1a; 题解&#xff1a; typedef struct {int start;int index; } Node;int cmp(const void *pa, const void *pb) {return ((Node *)pa)->start - ((Node *)pb)->start; }int* findRightInterval(int** intervals, int intervalsSize, int* intervalsColSiz…

网站建设中,JavaScript为什么现在可以做后台了?

JavaScript&#xff0c;作为一种最初为浏览器端脚本设计的语言&#xff0c;已经逐渐发展成为可以在服务器端运行的强大工具。以下是JavaScript可以做后台开发的原因分析&#xff1a; Node.js的崛起 事件驱动与非阻塞I/O&#xff1a;Node.js的事件驱动和非阻塞I/O模型使得JavaSc…

uniapp实现展示1个或多个文字标签,可点击切换选中、不选中的状态

前言 uni-tag是uni-app框架提供的一个标签组件&#xff0c;用于展示标签或者标记某个元素。它可以在视图中用来显示一组标签&#xff0c;并且支持自定义样式和事件。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 uni-notice-bar组件具有以下特点&…

利用千帆SDK实现作文自动批改

目录 作文批改实操 0. 环境准备 1. 大模型推理调用 1.1 Prompt 初探&#xff08;尝试到优化&#xff09; 1.2 Prompt 自动优化迭代&#xff08;APO&#xff1a;Automatic Prompt Optimization&#xff09; 1.3 推理超参优化&#xff08;autotuner&#xff09; 1.3.1 准备…

MATLAB案例 | 基于Copula的可靠度分析

本文详细介绍了Copula函数的绘制及在可靠度分析中的应用 各种类型Copula函数绘图完整代码例题1完整代码例题2完整代码各种类型Copula函数绘图 完整代码 clear clcy_gaussian = copularnd(gaussian, 0.9, 1000); y_t = copularnd(t, 0.91, 17.53,1000); y_Gumbel = copularnd(G…

【Java网络编程】使用Tcp和Udp实现一个小型的回声客户端服务器程序

网络编程的概念 Java中的网络编程是指使用Java语言及其库创建和管理网络应用程序的过程。这一过程使得不同的计算机可以通过网络进行通信和数据交换。Java提供了一系列强大的API&#xff08;应用程序编程接口&#xff09;来支持网络编程&#xff0c;主要涉及以下几个概念&…

AtCoder Beginner Contest 372

A - delete . 题目&#xff1a; 代码&#xff1a; #include <bits/stdc.h>using namespace std;typedef long long LL;int main() {string s;cin>>s;for(auto &x: s){if(x!.) cout<<x;}return 0; } B - 3^A 题目&#xff1a; 思路&#xff1a; 预处…

基于Node.js+Express+MySQL+VUE新闻网站管理系统的设计与实现

1. 引言 随着互联网技术的发展&#xff0c;人们获取信息的方式发生了巨大的变化。传统的新闻媒体逐渐向数字化、智能化方向发展。新闻推荐网站管理系统能够帮助新闻网站更好地管理和推荐新闻内容&#xff0c;提高用户体验。本文将详细介绍一个新闻推荐网站管理系统的整体设计与…