news 2026/5/23 13:46:37

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

作者头像

张小明

前端开发工程师

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/5/21 17:59:54

2026年,高科技制造行业CRM平台全景解析

一、行业特点与 CRM 需求1. 核心业务特性销售周期长&#xff1a;从需求确认到交付可达数月至数年决策链复杂&#xff1a;涉及技术、采购、财务、高层等多部门审批高度定制化&#xff1a;产品规格、技术参数需深度定制&#xff0c;报价复杂技术驱动&#xff1a;客户需求常需转化…

作者头像 李华
网站建设 2026/5/21 22:30:54

企业级工作流设计秘诀(基于Dify的动态条件路由实现方案)

第一章&#xff1a;企业级工作流设计的核心挑战在构建企业级应用系统时&#xff0c;工作流设计是决定系统可维护性、扩展性和可靠性的关键环节。复杂业务逻辑的流程化管理面临多重挑战&#xff0c;包括状态一致性保障、任务调度可靠性、跨服务协同以及异常处理机制等。状态管理…

作者头像 李华
网站建设 2026/5/12 6:42:43

ESP8266烧入AT固件,并且用AT固件连YY天气平台。

丫丫天气平台网址&#xff1a;http://www.yytianqi.com/ 下方是要通过串口发送的数据&#xff0c;文章后面有用到。 测试 AT 启动 AT 设置 Wi-Fi 模式 Station ATCWMODE1 重启模块 ATRST 连接 的WiFi名称&#xff08;”11“的地方填自己的WiFi的名称&#xff0c;“66666666”…

作者头像 李华
网站建设 2026/5/23 3:14:16

MATLAB分步傅里叶法仿真:光纤激光器锁模脉冲产生及可饱和吸收镜导致的脉冲漂移问题的解决

MATLAB分步傅里叶法仿真光纤激光器锁模脉冲产生 解决了可饱和吸收镜导致的脉冲漂移问题锁模光纤激光器的数值仿真就像在钢丝绳上跳舞——既要准确描述非线性效应&#xff0c;又要处理色散带来的时空畸变。去年实验室里那台掺镱光纤激光器总出现脉冲位置漂移&#xff0c;后来发现…

作者头像 李华
网站建设 2026/5/10 3:29:24

DAY32 Linux Thread Programming

Linux Thread Programming I. Core Theoretical Foundations of Threads 1. What is a Thread? Definition: A thread is an execution unit within a process, also referred to as a “Lightweight Process (LWP)”. It belongs to a specific process and shares the proce…

作者头像 李华