news 2026/9/1 12:58:09

堆与优先级队列:算法高效利器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
堆与优先级队列:算法高效利器

堆(heap)实际就是完全二叉树,但他的结点的值有两种趋势,一是从根节点的值到叶子节点的值从小到大称为小根堆,从根节点的值从大到小称为大根堆,否则不是堆。

当堆中插入数据或删除数据时,有向上调整算法和向下调整算法。

向上调整算法:当堆中插入数据,放在末尾,再逐渐向上调。以大根堆举例:

1:插入点与父节点的值比较,若是该点值大于父节点值,则交换。

2:重复1操作,直到小于父节点的值或交换到根节点为止。

void up(int child) { int parent = child / 2; while (parent >= 1 && heap[parent] <= heap[child]) { swap(heap[parent], heap[child]); child = parent; parent = child / 2; } }

向下调整算法:用于删除堆顶元素,堆排序的堆操作。以大根堆举例

1:找到左右孩子节点中值最大的节点,若该节点值小于孩子中值最大的节点,二者交换。

2:重复1操作,直到该点的值比两个孩子节点的值多大或换到叶子节点为止。

void down(int parent) { int child = parent * 2; while (child <= n) { if (child + 1 <= n && heap[child + 1] >= heap[child]) { child++; } if (heap[child] <= heap[parent]) { return; } swap(heap[child], heap[parent]); parent = child; child = parent * 2; } }

时间复杂度为O(logN)。

堆模拟实验:创建一个堆后,插入元素,然后执行向上调整算法:

void up(int child)//向上调整算法 { int parent = child / 2; while (parent >= 1 && heap[parent] <= heap[child]) { swap(heap[parent], heap[child]); child = parent; parent = child / 2; } } void push(int num)//插入元素 { heap[++n] = num; up(num); }

执行堆的删除元素:

void down(int parent)//向下调整算法 { int child = parent * 2; while (child <= n) { if (child + 1 <= n && heap[child + 1] >= heap[child]) { child++; } if (heap[child] <= heap[parent]) { return; } swap(heap[child], heap[parent]); parent = child; child = parent * 2; } } void pop(int num)//删除元素 { swap(heap[1], heap[n]); n--; down(1); }

根据以上内容我们大致了解了堆的基本概念和内容,接下来再衔接优先级队列priority_queue就简单许多。

priority_queue实际上可以近似认为是堆的数据结构,在普通的队列是先进先出,优先级队列也是如此,但它会根据元素的优先级自动排序,优先级最高的最先被删除。

它有许多便利的函数:

#include <iostream> #include <queue> using namespace std; priority_queue<int>heap; int main() { for (int i = 1; i <= 10; i++) { heap.push(i);//时间复杂度为O(logN). } int t = heap.top();//时间复杂度为O(1). heap.pop();//时间复杂度为O(logN). int m = heap.size();//时间复杂度为O(1). if (heap.empty())//时间复杂度为O(1). { cout << 1 << endl; } return 0; }

(其中函数的时间复杂度在注释中)

优先级队列中含有内置类型和结构体类型,正常创建时默认为大根堆

priority_queue<int>heap;//默认为大根堆

如果需要变为小根堆请看代码:

priority_queue<int, vector<int>, less<int>>heap1;//大根堆 priority_queue<int, vector<int>, greater<int>>heap2;//小根堆

结构体类型的模拟相对复杂,还需要用operator的重载运算符,需要在结构体内部来定义大小堆:

struct node { int ans; bool operator <(const node& x)const//利用operator的重载运算符'<'来定义 { return ans < x.ans;//如果是'<'就是大根堆,是'>'就是小根堆 } }; priority_queue<node>heap;

以上就是堆和优先级队列的全部内容,如果在算法题中若是观察到有单调性的题目,我们可以在被时间复杂度限制时,运用以上内容。

完结撒花!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 18:28:34

R语言在气象数据分析中的应用(相关性建模全攻略)

第一章&#xff1a;R语言在气象数据分析中的相关性建模概述 R语言因其强大的统计分析能力和丰富的可视化工具&#xff0c;成为气象数据分析中相关性建模的首选编程环境。气象数据通常具有高维度、时间序列性强和空间异质性等特点&#xff0c;R提供了如dplyr、tidyr、ggplot2和l…

作者头像 李华
网站建设 2026/8/31 11:50:19

揭秘Docker Compose中的Agent健康检测机制:如何避免服务假死?

第一章&#xff1a;揭秘Docker Compose中的Agent健康检测机制&#xff1a;如何避免服务假死&#xff1f;在微服务架构中&#xff0c;容器化应用的稳定性依赖于精确的健康状态判断。Docker Compose 提供了内置的 healthcheck 指令&#xff0c;用于监控服务容器的运行状态&#x…

作者头像 李华
网站建设 2026/9/1 3:51:22

Python期末复习:30个核心知识点完全详解

&#x1f3af; 第一部分&#xff1a;基础语法与数据类型&#xff08;共8个知识点&#xff09; 知识点1&#xff1a;变量与赋值操作 详细内容&#xff1a;变量命名规则 由字母、数字、下划线组成不能以数字开头区分大小写不能使用Python关键字建议使用小写字母和下划线组合&…

作者头像 李华
网站建设 2026/8/31 23:36:35

大模型训练数据全攻略:从数据处理到高质量数据集构建(建议收藏)

本文详细介绍了大模型训练数据的种类、处理流程和特点。通过高质量数据构建可大幅降低训练数据规模&#xff0c;阐述了质量过滤、冗余去除、隐私消除等预处理方法&#xff0c;以及人工标注数据的类型和用途。介绍了SFT、RM、PPO三类数据集的准备&#xff0c;自动化算法和多模态…

作者头像 李华
网站建设 2026/8/31 11:32:25

企业级容器安全迫在眉睫,Docker Scout如何实现小时级响应?

第一章&#xff1a;企业级容器安全的挑战与Docker Scout的定位在现代云原生架构中&#xff0c;容器技术已成为应用部署的核心载体&#xff0c;但其广泛使用也带来了复杂的安全挑战。企业面临镜像来源不可信、依赖漏洞隐蔽性强、运行时行为难以监控等问题&#xff0c;传统的安全…

作者头像 李华
网站建设 2026/8/31 11:59:00

12th Live2D Creative Awards(2025)获奖名单公布!

2025年度『第12届Live2D原创作品大赛』获奖者正式公布了&#xff01; 12月12日&#xff08;周五&#xff09;&#xff0c;我们在Live2D创作者峰会活动『alive 2025』中对获奖作品进行了颁奖仪式。 https://www.live2d.com/zh-CHS/event/awards12/ 什么是『Live2D Creative Aw…

作者头像 李华