news 2026/4/18 10:12:14

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

作者头像

张小明

前端开发工程师

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/4/16 12:48:09

用C# WinForm打造MES管理系统:从通讯到生产管理的实现

C#开发MES系统程序源码 c#winform MES管理系统源码1.该系统用C#.net开发&#xff0c;与7台西门子plc以太网通讯&#xff0c;生产数据收集&#xff0c;设备状态显示&#xff0c;生产管理等在工业4.0的浪潮下&#xff0c;MES&#xff08;制造执行系统&#xff09;成为企业实现智能…

作者头像 李华
网站建设 2026/4/18 8:19:55

异常频发怎么办?,一文读懂Dify与Spring AI协同容错设计精髓

第一章&#xff1a;异常频发怎么办&#xff1f;——Dify与Spring AI协同容错设计概述在构建基于AI服务的现代应用时&#xff0c;异常响应、网络波动和模型超时等问题频繁出现。Dify作为低代码AI编排平台&#xff0c;与Spring AI框架深度集成后&#xff0c;需具备强健的容错能力…

作者头像 李华
网站建设 2026/4/17 9:00:51

Datawhale Hello-Agents入门篇202512第1次作业

作业 首先&#xff0c;确保你的电脑上已经安装了必要的库&#xff1a; pip install requests python-dotenv tavily-python openai python-dotenv 用于读取 .env 环境变量文件其他库是原代码中已用到的&#xff08;网络请求、Tavily 搜索、OpenAI 兼容客户端&#xff09; 1…

作者头像 李华
网站建设 2026/3/30 12:34:01

震惊!想知道专业宠物美容培训学校哪家好?看这就够了!

震惊&#xff01;想知道专业宠物美容培训学校哪家好&#xff1f;看这就够了&#xff01;在宠物行业蓬勃发展的当下&#xff0c;宠物美容师成为了备受关注的职业。专业的宠物美容不仅能提升宠物的外观形象&#xff0c;还对宠物的健康有着重要意义。那么&#xff0c;专业宠物美容…

作者头像 李华
网站建设 2026/4/18 7:55:30

CLLC双向谐振变换器仿真那些事儿

CLLC双向谐振变换器仿真。 输出电压闭环控制。 采用CLLC对称结构&#xff0c;正反两个方向的运行对称。 模型可以实现自动的正反向运行。 如效果图2所示: 在0.2s处&#xff0c;电路由正向传输改为反向传输。 有plecs/matlab/simulink在电力电子领域&#xff0c;CLLC双向谐振变换…

作者头像 李华